TITLE TEST1 11/28/83 ROM POST

;--------------------------------------------------------------------
; BIOS I/O INTERFACE						    ;
;								    ;
;	THESES INTERFACE LISTINGS, PROVIDE ACCESS TO BIOS ROUTINES  ;
;	THESE BIOS ROUTINES ARE MEANT TO BE ACCESSED THROUGH	    ;
;	SOFTWARE INTERRUPTS ONLY.  ANY ADDRESSES PRESENT IN	    ;
;	THE LISTINGS  ARE INCLUDED  ONLY FOR  COMPLETENESS,	    ;
;	NOT FOR  REFERENCE.   APPLICATIONS WHICH  REFERENCE	    ;
;	ABSOLUTE   ADDRESSES   WITHIN	THE   CODE  SEGMENT	    ;
;	VIOLATE THE STRUCTURE AND DESIGN OF BIOS.		    ;
;								    ;
;--------------------------------------------------------------------
PAGE
;----------------------------------------------------------------
; MODULES REQUIRED
;
;	DATA.SRC	-->   DATA AREA
;	TEST1.SRC	-->   TEST.01 THRU TEST.16
;	TEST2.SRC	-->   TEST.17 THRU TEST.22
;	TEST3.SRC	-->   PROCEDURES
;				ROS_CHECKSUM
;				BLINK_INT
;				ROM_CHECK
;				XPC_BYTE
;				PRT_HEX
;				PROT_PRT_HEX
;				PROC_SHUTDOWN
;	TEST4.SRC	-->	E_MSG
;				P_MSG
;				BEEP
;				ERR_BEEP
;				KBD_RESET
;				D11 DUMMY INT HANDLER
;				INT13 - X287 HANDLER
;				PRT_SEG
;				DDS
;				HARDWARE INT 9 HANDLER (TYPE 71)
;	TEST5.SRC	-->   EXCEPTTON INTERRUPTS
;	TEST6.SRC	-->	STGTST_CNT
;				ROM_ERR
;				XMIT_8042
;				BOOT_STRAP
;	TEST7.SRC	-->   PROTECTED MODE TEST
;	SYSINIT1.SRC	-->   BUILD PROTECTED MODE DESCRIPTORS
;	  GDT_BLD.SRC
;	  SIDT_BLD.SRC
;	DSKETTE.SRC	-->  DISKETTE BIOS
;	DISK.SRC	-->  HARD FILE BIOS
;	KYBD.SRC	-->  KEYBOARD BIOS
;	PRT.SRC 	-->  PRINTER BIOS
;	RS232.SRC	-->  RS232 BIOS
;	VIDEO1.SRC	-->  VIDEO BIOS
;	BIOS.SRC	-->    MEM_SIZE
;			       EQUIP_DET
;			       NMI
;			       SET_TOD
;	BIOS1.SRC	-->  DUMMY CASSETTE (INT 15)
;			       DEVICE OPEN
;			       DEVICE CLOSE
;			       PROGRAM TERMINATION
;			       EVENT WAIT
;			       JOYSTICK SUPPORT
;			       SYSTEM REQUEST
;			       WAIT
;			       MOVE BLOCK
;			       EXTENDED MEMORY SIZE DETERMINE
;			       PROCESSOR TO VIRTUAL MODE
;	BIOS2.SRC	-->    TIME OF DAY
;			       TIMER1 INT
;			       PRINT_SCREEN
;	ORGS.SRC	-->  PC COMPATIBILITY AND TABLES
;			       POST ERROR MESSAGES
;----------------------------------------------------------------
INCLUDE POSTEQU.SRC
INCLUDE DSEG.SRC
.XLIST
INCLUDE SYSDATA.INC
INCLUDE IAPX286.MAC
.LIST
INCLUDE SEGMENT.SRC
EXTRN	VIDEO_PARMS:BYTE
EXTRN	POST2:NEAR
EXTRN	DDS:NEAR
EXTRN	D11:NEAR
EXTRN	VECTOR_TABLE:NEAR
EXTRN	KBD_RESET:NEAR
EXTRN	DUMMY_RETURN:NEAR
EXTRN	STGTST_CNT:NEAR
EXTRN	ERR_BEEP:NEAR
EXTRN	ROM_CHECK:NEAR
EXTRN	ROS_CHECKSUM:NEAR
EXTRN	SYSINIT1:NEAR
EXTRN	SHUT2:NEAR
EXTRN	SHUT3:NEAR
EXTRN	SHUT4:NEAR
EXTRN	SHUT6:NEAR
EXTRN	SHUT7:NEAR
EXTRN	SHUT9:NEAR
EXTRN	PROC_SHUTDOWN:NEAR
EXTRN	C1:NEAR
EXTRN	C2:NEAR
EXTRN	C8042A:NEAR
EXTRN	OBF_42A:NEAR
EXTRN	C8042B:NEAR
EXTRN	C8042C:NEAR
EXTRN	OBF_42B:NEAR
EXTRN	F3B:NEAR
EXTRN	SLAVE_VECTOR_TABLE:NEAR
EXTRN	NMI_INT:NEAR
EXTRN	PRINT_SCREEN:NEAR
EXTRN	GATE_A20:NEAR

	ASSUME	CS:CODE,SS:CODE,ES:ABS0,DS:DATA

PUBLIC	POST1
PUBLIC	BEGIN
PUBLIC	CHK_VIDEO
PUBLIC	START_1
PUBLIC	C8042
PUBLIC	OBF_42
PUBLIC	C11
PUBLIC	C30
PUBLIC	TST4_B
PUBLIC	TST4_C
PUBLIC	TST4_D
PUBLIC	E30B
PUBLIC	E30C

BEGIN	EQU	$

	;	 6 1 8 1 0 2 8	 C O P R .   I B M   1 9 8 4   ;EVEN
	;	  6 1 8 1 0 2 9   C O P R .   I B M   1 9 8 4  ;ODD
	DB	'66118811002289  CCOOPPRR..  IIBBMM  11998844' ;COPYRIGHT NOTICE

;------------------------------------------------
;	INITIAL RELIABILITY TESTS -- PHASE 1	:
;------------------------------------------------
POST1	PROC	NEAR
;--------------------------------------------------------------------
;	LOAD A BLOCK OF TEST CODE THROUGH THE KEYBOARD PORT	    :
;	FOR MANUFACTURING TEST. 				    :
;	THIS ROUTINE WILL LOAD A TEST (MAX LENGTH=FAFFH) THROUGH    :
;	THE KEYBOARD PORT. CODE WILL BE LOADED AT LOCATION	    :
;	0000:0500. AFTER LOADING, CONTROL WILL BE TRANSFERED	    :
;	TO LOCATION 0000:0500. STACK WILL BE LOCATED AT 30:100	    :
;	THIS ROUTINE ASSUMES THAT THE FIRST 2			    :
;	BYTES TRANSFERED CONTAIN THE COUNT OF BYTES TO BE LOADED    :
;	(BYTE 1=COUNT LOW, BYTE 2=COUNT HI.)			    :
;--------------------------------------------------------------------

MFG_BOOT:
	CLI				; NO INTERRUPTS

;------- DEGATE ADDRESS LINE 20

	MOV	AH,DISABLE_BIT20	; DEGATE COMMAND
	CALL	GATE_A20		; ISSUE TO COMMAND

;------- SETUP HARDWARE INT VECTOR TABLE LVL 0-7

	SUB	AX,AX			;
	MOV	ES,AX
	MOV	CX,08			; GET VECTOR CNT
	PUSH	CS			; SETUP DS SEG REG
	POP	DS
	MOV	SI,OFFSET VECTOR_TABLE
	MOV	DI,OFFSET INT_PTR
MFG_B:	MOVSW
	INC	DI			; SKIP OVER SEGMENT
	INC	DI
	LOOP	MFG_B

;------- SETUP HARDWARE INT VECTOR TABLE LVL 8-15 (VECTORS START AT INT 70H)

	SUB	AX,AX			;
	MOV	ES,AX
	MOV	CX,08			; GET VECTOR CNT
	PUSH	CS			; SETUP DS SEG REG
	POP	DS
	MOV	SI,OFFSET SLAVE_VECTOR_TABLE
	MOV	DI,OFFSET SLAVE_INT_PTR
MFG_C:	MOVSW
	INC	DI			; SKIP OVER SEGMENT
	INC	DI
	LOOP	MFG_C

;----- SET UP OTHER INTERRUPTS AS NECESSARY

	ASSUME	DS:ABS0
	ASSUME	ES:ABS0 			; DS=0
	SUB	AX,AX
	MOV	DS,AX
	MOV	ES,AX				; ES=0
	MOV	NMI_PTR,OFFSET NMI_INT		; NMI INTERRUPT
	MOV	INT5_PTR,OFFSET PRINT_SCREEN	; PRINT SCREEN
	MOV	BASIC_PTR+2,0F600H		; SEGMENT FOR CASSETTE BASIC

;------- ENABLE KEYBOARD PORT

	MOV	AL,60H			; WRITE 8042 RAM 0
	CALL	C8042			; ISSUE THE COMMAND
	MOV	AL,00001001B		; SET INHIBIT OVERRIDE/ENABLE OBF INT
	OUT	PORT_A,AL		;   AND NOT PC COMP

	CALL	MFG_2			; GET COUNT LOW
	MOV	BH,AL			; SAVE IT
	CALL	MFG_2			; GET COUNT HI
	MOV	CH,AL			;
	MOV	CL,BH			; CX NOW HAS COUNT
	CLD				; SET DIR. FLAG TO INCREMENT
	MOV	DI,0500H		; SET TARGET OFFSET (DS=0000)
MFG_1:
	IN	AL,STATUS_PORT		; GET 8042 STATUS PORT
	TEST	AL,OUT_BUF_FULL 	; KB REQUEST PENDING?
	JZ	MFG_1			; LOOP TILL DATA PRESENT
	IN	AL,PORT_A		; GET DATA
	STOSB				; STORE IT

	OUT	MFG_PORT,AL		; DISPLAY CHAR AT MFG PORT

	LOOP	MFG_1			; LOOP TILL ALL BYTES READ

	JMP	MFG_TEST_RTN		; FAR JUMP TO CODE THAT WAS JUST
					; LOADED
MFG_2:
	IN	AL,STATUS_PORT		; CHECK FOR OUTPUT BUFF FULL
	TEST	AL,OUT_BUF_FULL 	;   HANG HERE IF NO DATA AVAILABLE
	LOOPZ	MFG_2

	IN	AL,PORT_A		; GET THE COUNT
	RET				;

;----------------------------------------
; TEST.01				:
;	X286 PROCESSOR TEST (REAL MODE) :
; DESCRIPTION				:
;	VERIFY FLAGS, REGISTERS 	:
;	AND CONDITIONAL JUMPS.		:
;----------------------------------------
	ASSUME	CS:CODE,DS:DATA,ES:NOTHING,SS:NOTHING
START_1: CLI				; DISABLE INTERRUPTS
	 MOV	 AH,0D5H		; SET SF, CF, ZF, AND AF FLAGS ON
	 SAHF
	 JNC	 ERR02			; GO TO ERR ROUTINE IF CF NOT SET
	 JNZ	 ERR02			; GO TO ERR ROUTINE IF ZF NOT SET
	 JNP	 ERR02			; GO TO ERR ROUTINE IF PF NOT SET
	 JNS	 ERR02			; GO TO ERR ROUTINE IF SF NOT SET
	 LAHF				; LOAD FLAG IMAGE TO AH
	 MOV	 CL,5			; LOAD CNT REG WITH SHIFT CNT
	 SHR	 AH,CL			; SHIFT AF INTO CARRY BIT POS
	 JNC	 ERR02			; GO TO ERR ROUTINE IF AF NOT SET
	 MOV	 AL,40H 		; SET THE OF FLAG ON
	 SHL	 AL,1			; SETUP FOR TESTING
	 JNO	 ERR02			; GO TO ERR ROUTINE IF OF NOT SET
	 XOR	 AH,AH			; SET AH = 0
	 SAHF				; CLEAR SF, CF, ZF, AND PF
	 JBE	 ERR02			; GO TO ERR ROUTINE IF CF ON
					; GO TO ERR ROUTINE IF ZF ON
	 JS	 ERR02			; GO TO ERR ROUTINE IF SF ON
	 JP	 ERR02			; GO TO ERR ROUTINE IF PF ON
	 LAHF				; LOAD FLAG IMAGE TO AH
	 MOV	 CL,5			; LOAD CNT REG WITH SHIFT CNT
	 SHR	 AH,CL			; SHIFT 'AF' INTO CARRY BIT POS
	 JC	 ERR02			; GO TO ERR ROUTINE IF ON
	 SHL	 AH,1			; CHECK THAT 'OF' IS CLEAR
	 JO	 ERR02			; GO TO ERR ROUTINE IF ON
	 JMP	 C7A			; CONTINUE
ERR02:	 JMP	 ERR01			; ERROR EXIT

C7A:
	MOV	AX,DATA 		; SET DATA SEGMENT
	MOV	DS,AX


;----- CHECK FOR PROCESSOR SHUTDOWN

	IN	AL,STATUS_PORT		; CHECK FOR SHUTDOWN
	TEST	AL,SYS_FLAG		;
	JNZ	C7B			; GO IF YES
	JMP	C7			;

;------ CHECK FOR SHUTDOWN 09
C7B:
	MOV	AL,SHUT_DOWN		; CMOS ADDR FOR SHUTDOWN BYTE
	OUT	CMOS_PORT,AL
	JMP	SHORT $+2		; IO DELAY
	IN	AL,CMOS_PORT+1		; GET WHO
	XCHG	AL,AH			; SAVE THE SHUTDOWN REQUEST
	CMP	AH,09H			; WAS IT SHUTDOWN REQUEST 9?
	JZ	C7C			; BYPASS INIT OF INT CHIPS
;--------------------------------------------------------
;    RE-INITIALIZE THE 8259 INTERRUPT #1 CONTROLLER CHIP :
;--------------------------------------------------------

	SUB	AL,AL			; INSURE MATH PROCESSOR RESET
	OUT	X287+1,AL		;
	MOV	AL,11H			; ICW1 - EDGE, MASTER, ICW4
	OUT	INTA00,AL
	JMP	SHORT $+2		; WAIT STATE FOR IO
	MOV	AL,8			; SETUP ICW2 - INT TYPE 8 (8-F)
	OUT	INTA01,AL
	JMP	SHORT $+2		; WAIT STATE FOR IO

	MOV	AL,04H			; SETUP ICW3 - MASTER LV 2
	OUT	INTA01,AL
	JMP	SHORT $+2		; IO WAIT STATE
	MOV	AL,01H			; SETUP ICW4 - MASTER,8086 MODE
	OUT	INTA01,AL		;
	JMP	SHORT $+2		; WAIT STATE FOR IO
	MOV	AL,0FFH 		; MASK ALL INTS. OFF
	OUT	INTA01,AL		; (VIDEO ROUTINE ENABLES INTS.)
;---------------------------------------------------------
;    RE-INITIALIZE THE 8259 INTERRUPT #2 CONTROLLER CHIP  :
;---------------------------------------------------------

	MOV	AL,11H			; ICW1 - EDGE, SLAVE ICW4
	OUT	INTB00,AL
	JMP	SHORT $+2		; WAIT STATE FOR IO
	MOV	AL,INT_TYPE		; SETUP ICW2 - INTERRUPT TYPE 70 (70-7F)
	OUT	INTB01,AL		;
	MOV	AL,02H			; SETUP ICW3 - SLAVE LV 2
	JMP	SHORT $+2		;
	OUT	INTB01,AL		;
	JMP	SHORT $+2		; IO WAIT STATE
	MOV	AL,01H			; SETUP ICW4 - 8086 MODE, SLAVE
	OUT	INTB01,AL		;
	JMP	SHORT $+2		; WAIT STATE FOR IO
	MOV	AL,0FFH 		; MASK ALL INTS. OFF
	OUT	INTB01,AL		;
;------------------------------------------------------------
;  SHUTDOWN						    :
;	RETURN CONTROL AFTER A SHUTDOWN COMMAND IS ISSUED   :
;  DESCRIPTION						    :
;	A TEST IS MADE FOR THE SYSTEM FLAG BEING SET.  IF   :
;	THE SYSTEM FLAG IS SET, THE SHUTDOWN BYTE IN CMOS   :
;	IS USED TO DETERMINE WHERE CONTROL IS RETURNED.     :
;							    :
;	CMOS = 0     SOFT RESET OR UNEXPECTED SHUTDOWN	    :
;	CMOS = 1     SHUT DOWN AFTER MEMORY SIZE	    :
;	CMOS = 2     SHUT DOWN AFTER MEMORY TEST	    :
;	CMOS = 3     SHUT DOWN WITH MEMORY ERROR	    :
;	CMOS = 4     SHUT DOWN WITH BOOT LOADER REQUEST     :
;	CMOS = 5     JMP DWORD REQUEST (WITH INT INIT)	    :
;	CMOS = 6     PROTECTED MODE TEST7 PASSED	    :
;	CMOS = 7     PROTECTED MODE TEST7 FAILED	    :
;	CMOS = 8     PROTECTED MODE TEST1 FAILED	    :
;	CMOS = 9     BLOCK MOVE SHUTDOWN REQUEST	    :
;	CMOS = A     JMP DWORD REQUEST (W/O INT INIT)	    :
;------------------------------------------------------------
;-----	CHECK FROM WHERE
C7C:	MOV	AL,SHUT_DOWN		; CLEAR CMOS BYTE
	OUT	CMOS_PORT,AL
	JMP	SHORT $+2		; IO DELAY
	SUB	AL,AL			; SET BYTE TO 0
	OUT	CMOS_PORT+1,AL		;
	XCHG	AH,AL			;
	CMP	AL,0AH			; MAX TABLE ENTRYS
	JA	SHUT0			; GO IF GREATER THAN MAX
	MOV	SI,OFFSET BRANCH      ; GET THE START OF BRANCH TABLE
	ADD	SI,AX			;
	ADD	SI,AX			; POINT TO BRANCH ADDRESS
	MOV	BX,CS:[SI]		; GET BRANCH TO BX
	CLI
	MOV	AX,STACK		; SET STACK
	MOV	SS,AX			;
	MOV	SP,OFFSET TOS		;
	STI				;
	JMP	BX			; JUMP BACK

BRANCH: DW	SHUT0			; NORMAL POWER UP/UNEXPECTED SHUTDOWN
	DW	SHUT1			; SHUT DOWN AFTER MEMORY SIZE
	DW	SHUT2			; SHUT DOWN AFTER MEMORY TEST
	DW	SHUT3			; SHUT DOWN WITH MEMORY ERROR
	DW	SHUT4			; SHUT DOWN WITH BOOT_LOADER REQUEST
	DW	SHUT5			; JMP DWORD REQUEST (WITH INTERRUPT INIT)
	DW	SHUT6			; PROTECTED MODE TEST7 PASSED
	DW	SHUT7			; PROTECTED MODE TEST7 FAILED
	DW	SHUT8			; PROTECTED MODE TEST1 FAILED
	DW	SHUT9			; BLOCK MOVE SHUTDOWN REQUEST
	DW	SHUTA			; JMP DWORD REQUEST (W/O INTERRUPT INIT)
SHUT0:	JMP	C7

;------- IO_ROM_INIT MUST BE INITIALIZED BY THE USER
					; FLUSH THE KEYBOARD BUFFER
SHUT5:	IN	AL,STATUS_PORT		; CHECK IF OUTPUT BUFFER FULL
	TEST	AL,OUT_BUF_FULL
	JZ	SHUT5B			; GO IF NOT
	IN	AL,PORT_A		; FLUSH
SHUT5B: MOV	AL,EOI			; FLUSH LAST TIMER TICK
	OUT	INTA00,AL		; -TO ALLOW TIMER INTERRUPTS

SHUTA:	JMP	DWORD PTR DS:IO_ROM_INIT;

;----- CHECKPOINT 01

C7:	MOV	AL,01H			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 1<><><>

;----- READ/WRITE THE X286 GENERAL AND SEGMENTATION REGISTERS
;	WITH ALL ONE'S AND ZEROES'S.

	MOV	AX,0FFFFH		; SETUP ONE'S PATTERN IN AX
	STC				; SET CARRY FLAG
	JNC	ERR01			; GO IF NO CARRY
C8:	MOV	DS,AX			; WRITE PATTERN TO ALL REGS
	MOV	BX,DS
	MOV	ES,BX
	MOV	CX,ES
	MOV	SS,CX
	MOV	DX,SS
	MOV	SP,DX
	MOV	BP,SP
	MOV	SI,BP
	MOV	DI,SI
	JNC	C9			;
	XOR	AX,DI			; PATTERN MAKE IT THRU ALL REGS
	JNZ	ERR01			; NO - GO TO ERR ROUTINE
	CLC				; CLEAR CARRY FLAG
	JMP	C8
C9:					; TST1A
	OR	AX,DI			; ZERO PATTERN MAKE IT THRU?
	JZ	C10A			; YES - GO TO NEXT TEST
ERR01:	HLT				; HALT SYSTEM
;------- INSURE THAT CMOS CLOCK INTERRUPTS ARE DISABLED


C10A:	MOV	AL,CMOS_ALARM		;
	OUT	CMOS_PORT,AL		;
	JMP	SHORT $+2		;
	IN	AL,CMOS_PORT+1		; GET THE CURRENT CONTROL REG
	XCHG	AL,AH			; SAVE IT
	AND	AH,07H			; CLEAR SET,PIE,AIE, AND SQWE BITS
	MOV	AL,CMOS_ALARM		;
	OUT	CMOS_PORT,AL		;
	XCHG	AL,AH			;
	JMP	SHORT $+2		; IO DELAY
	OUT	CMOS_PORT+1,AL		;

	JMP	SHORT $+2		; IO DELAY
	MOV	AL,CMOS_ALARM+1 	; CLEAR PENDING INTERRUPT
	OUT	CMOS_PORT,AL		;
	JMP	SHORT $+2		; IO DELAY
	IN	AL,CMOS_PORT+1		;

;-------- RESET VIDEO

	ASSUME	DS:DATA
	MOV	AX,DATA
	MOV	DS,AX			; SET DATA SEGMENT
	CMP	RESET_FLAG,1234H	; SOFT RESET?
	JZ	SFT_RST 		; GO IF YES

	SUB	AL,AL			;
	MOV	DX,3D8H
	OUT	DX,AL			; DISABLE COLOR VIDEO
	INC	AL
	MOV	DL,0B8H
	OUT	DX,AL			; DISABLE B/W VIDEO,EN HIGH RES
SFT_RST:MOV	AL,11111100B		; DISABLE PARITY CHECKERS
	OUT	PORT_B,AL		;

;------------------------------------------
; TEST.02				  :
;	VERIFY CMOS SHUTDOWN BYTE	  :
; DESCRIPTION				  :
;	ROLLING BIT WRITTEN AND VERIFIED  :
;	AT SHUTDOWN ADDRESS.		  :
;------------------------------------------

	MOV	AL,2			;<><><><><><><><><><><>
	OUT	MFG_PORT,AL		;<><><>CHECKPOINT 2<><>

;----- VERIFY AND CLEAR SHUTDOWN FLAG

	MOV	CX,09H			; LOOP COUNT
	MOV	AH,1			; START WITH BIT 0
C10B:	MOV	AL,SHUT_DOWN		;
	OUT	CMOS_PORT,AL		;
	MOV	AL,AH			; OUTPUT ROLLING BIT
	JMP	SHORT $+2		; IO DELAY
	OUT	CMOS_PORT+1,AL		;
	MOV	AL,SHUT_DOWN		; READ CMOS
	JMP	SHORT $+2		; IO DELAY
	OUT	CMOS_PORT,AL
	JMP	SHORT $+2		; IO DELAY
	IN	AL,CMOS_PORT+1		;
	CMP	AL,AH			; MUST BE THE SAME
	JNZ	ERR01			; ERROR IF NOT
	RCL	AH,1			; ROLL A BIT THRU SHUT DOWN
	LOOP	C10B			; LOOP TILL DONE


;----------------------------------------
; TEST.03				:
;	ROS CHECKSUM TEST I		:
; DESCRIPTION				:
;	A CHECKSUM IS DONE FOR THE 32K	:
;	ROS MODULES CONTAINING POD AND	:
;	BIOS.				:
;----------------------------------------
C10:
;----- CHECKPOINT 3

	MOV	AL,03H			;<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;<><><>CHECKPOINT 3<><><>

					;
	MOV	AX,CS			; SETUP SS SEG REG
	MOV	SS,AX
	MOV	DS,AX			; SET UP DATA SEG TO POINT TO  ========
					; ROM ADDRESS
	ASSUME	SS:CODE
	MOV	BX,OFFSET BEGIN 	; SETUP STARTING ROS ADDR
	MOV	SP,OFFSET C1		; SETUP RETURN ADDRESS
	JMP	ROS_CHECKSUM
C11:
	JZ	C11A			; HALT SYSTEM IF ERROR
	HLT
;-------------------------------------------
; TEST.04				   :
;	8253 CHECK TIMER 1 ALL BITS ON	   :
; DESCRIPTION				   :
;	SET TIMER COUNT 		   :
;	CHECK THAT TIMER 1 ALL BITS ON	   :
;------------------------------------------:
	ASSUME	DS:DATA
C11A:	MOV	AX,DATA 		; SET DATA SEGMENT
	MOV	DS,AX
	MOV	AL,04H			;<><><><><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;<><><><>CHECKPOINT 4<><><><><>

;----- DISABLE DMA CONTROLLER

;	MOV	AL,04			; AL ALREADY = 04H
	OUT	DMA08,AL		; DISABLE DMA CONTROLLER 1
	OUT	DMA18,AL		; DISABLE DMA CONTROLLER 2

;----- VERIFY THAT TIMER 1 FUNCTIONS OK

	MOV	DX,RESET_FLAG		; SAVE RESET FLAG WHILE REFRESH IS OFF
	MOV	AL,54H			; SEL TIMER 1,LSB,MODE 2
	OUT	TIMER+3,AL
	JMP	SHORT $+2		; WAIT STATE FOR IO
	MOV	AL,CL			; SET INITIAL TIMER CNT TO 0
	OUT	TIMER+1,AL
	MOV	BH,05H			; LOOP COUNT
C12:					; TIMER1_BITS_ON
	MOV	AL,40H			; LATCH TIMER 1 COUNT
	JMP	SHORT $+2		; IO DELAY
	OUT	TIMER+3,AL
	CMP	BL,0FFH 		; YES - SEE IF ALL BITS GO OFF
	JE	C13			; TIMER1_BITS_OFF
	IN	AL,TIMER+1		; READ TIMER 1 COUNT
	OR	BL,AL			; ALL BITS ON IN TIMER
	LOOP	C12			; TIMER1_BITS_ON
	DEC	BH			;
	JNZ	C12			;  TRY AGAIN
	HLT				; TIMER 1 FAILURE, HALT SYS
					; TIMER1_BITS_OFF
;-------------------------------------------------------
; TEST.05					       :
;	8254 CHECK TIMER 1 ALL BIT OFF		       :
; DESCRIPTION					       :
;	SET TIMER COUNT 			       :
;	CHECK THAT TIMER 1 ALL BITS OFF 	       :
;-------------------------------------------------------

;----- CHECKPOINT 5

C13:	MOV	AL,05H			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 5<><><>

	MOV	AL,BL			; SET TIMER 1 CNT
	SUB	CX,CX
	OUT	TIMER+1,AL
	MOV	BH,05H			; SET TRY AGAIN COUNT
C14:					; TIMER_LOOP
	JMP	SHORT $+2		;  IO DELAY
	MOV	AL,40H			; LATCH TIMER 1 COUNT
	OUT	TIMER+3,AL
	JMP	SHORT $+2		; DELAY FOR TIMER
	JMP	SHORT $+2		; ADDED DELAY FOR TIMER
	IN	AL,TIMER+1		; READ TIMER 1 COUNT
	AND	BL,AL
	JZ	C15			; WRAP_DMA_REG
	LOOP	C14			; TIMER_LOOP
	DEC	BH			;
	JNZ	C14			;
	HLT				; HALT SYSTEM
;--------------------------------------------------------
; TEST.06						:
;	8237 DMA 0 INITIALIZATION CHANNEL REGISTER TEST :
; DESCRIPTION						:
;	DISABLE THE 8237 DMA CONTROLLER.		:
;	WRITE/READ THE CURRENT				:
;	ADDRESS AND WORD COUNT REGISTERS FOR ALL	:
;	CHANNELS.					:
;--------------------------------------------------------

;----- CHECKPOINT 6

C15:
	MOV	AX,DATA 		; SET DATA SEGMENT
	MOV	DS,AX
	MOV	AL,06H			;<><><><><><><><><><><><>
	OUT	MFG_PORT,AL		;<><><>CHECKPOINT 6<><><>
	MOV	RESET_FLAG,DX		; RESTORE SOFT RESET FLAG
	OUT	DMA+0DH,AL		; SEND MASTER CLEAR TO DMA
;----- WRAP DMA 0 CHANNEL ADDRESS AND COUNT REGISTERS

	MOV	AL,0FFH 		; WRITE PATTERN FF TO ALL REGS
C16:	MOV	BL,AL			; SAVE PATTERN FOR COMPARE
	MOV	BH,AL
	MOV	CX,8			; SETUP LOOP CNT
	MOV	DX,DMA			; SETUP I/O PORT ADDR OF REG
C17:	OUT	DX,AL			; WRITE PATTERN TO REG, LSB
	JMP	SHORT $+2		; WAIT STATE FOR IO
	OUT	DX,AL			; MSB OF 16 BIT REG
	MOV	AL,01H			; AL TO ANOTHER PAT BEFORE RD
	JMP	SHORT $+2		; WAIT STATE FOR IO
	IN	AL,DX			; READ 16-BIT DMA CH REG, LSB 2ST DMA
	JMP	SHORT $+2		; WAIT STATE FOR IO
	MOV	AH,AL			; SAVE LSB OF 16-BIT REG
	IN	AL,DX			; READ MSB OF DMA CH REG
	CMP	BX,AX			; PATTERN READ AS WRITTEN?
	JE	C18			; YES - CHECK NEXT REG
	HLT				; NO - HALT THE SYSTEM
C18:					; NXT_DMA_CH
	INC	DX			; SET IO PORT TO NEXT CH REG
	LOOP	C17			; WRITE PATTERN TO NEXT REG
	INC	AL			; SET PATTERN TO 0
	JZ	C16			; YES CONTINUE

;------- WRITE DMA WITH 55 PATTERN

	CMP	BL,55H			; CHECK IF 55 PATTERN DONE
	JZ	C19			; GO IF YES
	CMP	BL,0AAH 		; CHECK IF AA PATTERN DONE
	JZ	C20			; GO IF YES
	MOV	AL,55H			;
	JMP	C16

;------- WRITE DMA WITH AA PATTERN

C19:	MOV	AL,0AAH 		;
	JMP	C16			;
;--------------------------------------------------------
; TEST.07						:
;	8237 DMA 1 INITIALIZATION CHANNEL REGISTER TEST :
; DESCRIPTION						:
;	DISABLE THE 8237 DMA CONTROLLER 1.		:
;	WRITE/READ THE CURRENT DMA 1			:
;	ADDRESS AND WORD COUNT REGISTERS FOR ALL	:
;	CHANNELS.					:
;--------------------------------------------------------

;------- CHECKPOINT 07 DMA 1

C20:	MOV	AL,07H			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 7<><><>
	OUT	DMA1+0DH*2,AL		; SEND MASTER CLEAR TO 2ND DMA

;----- WRAP DMA 1 CHANNEL ADDRESS AND COUNT REGISTERS

	MOV	AL,0FFH 		; WRITE PATTERN FF TO ALL REGISTERS
C16A:	MOV	BL,AL			; SAVE PATTERN FOR COMPARE
	MOV	BH,AL
	MOV	CX,8			; SETUP LOOP CNT
	MOV	DX,DMA1 		; SETUP I/O PORT ADDR OF REG
C17A:	OUT	DX,AL			; WRITE PATTERN TO REG, LSB
	JMP	SHORT $+2		; WAIT STATE FOR IO
	OUT	DX,AL			; MSB OF 16 BIT REG
	MOV	AL,01H			; AL TO ANOTHER PAT BEFORE RD
	JMP	SHORT $+2		; WAIT STATE FOR IO
	IN	AL,DX			; READ 16-BIT DMA CH REG, LSB 2ST DMA
	JMP	SHORT $+2		; WAIT STATE FOR IO
	MOV	AH,AL			; SAVE LSB OF 16-BIT REG
	IN	AL,DX			; READ MSB OF DMA CH REG
	CMP	BX,AX			; PATTERN READ AS WRITTEN?
	JE	C18A			; YES - CHECK NEXT REG
	HLT				; NO - HALT THE SYSTEM
C18A:					; NXT_DMA_CH
	ADD	DX,2			; SET IO PORT TO NEXT CH REG
	LOOP	C17A			; WRITE PATTERN TO NEXT REG
	INC	AL			; SET PATTERN TO 0
	JZ	C16A			; YES CONTINUE

;------- WRITE DMA WITH 55 PATTERN

	CMP	BL,55H			; CHECK IF 55 PATTERN DONE
	JZ	C20A			; GO IF YES
	CMP	BL,0AAH 		; CHECK IF AA PATTERN DONE
	JZ	C21			; GO IF YES
	MOV	AL,55H			;
	JMP	C16A

;------- WRITE DMA WITH AA PATTERN

C20A:	MOV	AL,0AAH 		;
	JMP	C16A			;

;----- INITIALIZE AND START MEMORY REFRESH.

C21:
	MOV	BX,RESET_FLAG		; GET THE RESET FLAG

	MOV	EQUIP_FLAG,AX		; DO A DUMMY WRITE RAM BEFORE REFRESH
	MOV	AL,18			; START TIMER
	OUT	TIMER+1,AL

;------- SET DMA COMMAND
C21Z:
	SUB	AL,AL			; DACK SENSE LOW,DREQ SENSE HIGH
	OUT	DMA+8,AL		; LATE WRITE, FIXED PRIORITY,NORMAL TIMING
					; CONTROLLER ENABLE,CH0 ADDR HOLD DISABLE
					; MEMORY TO MEM DISABLE
	OUT	DMA18,AL		; SAME TO SECOND CONTROLLER

;-------- MODE SET ALL DMA CHANNELS

	MOV	AL,40H			; SET MODE FOR CHANNEL 0
	OUT	DMA+0BH,AL		;
	MOV	AL,0C0H 		; SET CASCADE MODE ON CHANNEL 4
	OUT	DMA18+06H,AL		;
	JMP	SHORT $+2		; WAIT STATE FOR IO
	MOV	AL,41H			; SET MODE FOR CHANNEL 1
	OUT	DMA+0BH,AL
	OUT	DMA18+06H,AL		; SET MODE FOR CHANNEL 5
	JMP	SHORT $+2		; WAIT STATE FOR IO
	MOV	AL,42H			; SET MODE FOR CHANNEL 2
	OUT	DMA+0BH,AL
	OUT	DMA18+06H,AL		; SET MODE FOR CHANNEL 6
	JMP	SHORT $+2		; WAIT STATE FOR IO
	MOV	AL,43H			; SET MODE FOR CHANNEL 3
	OUT	DMA+0BH,AL
	OUT	DMA18+06H,AL		; SET MODE FOR CHANNEL 7

;------- RESTORE RESET FLAG

	MOV	RESET_FLAG,BX		;

;--------------------------------------------------------
; TEST.08						:
;	DMA PAGE REGISTER TEST				:
; DESCRIPTION						:
;	WRITE/READ ALL PAGE REGISTERS			:
;--------------------------------------------------------

;----- CHECK POINT 8

	MOV	AL,08H			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 8<><><>
	SUB	AL,AL			;
	MOV	DX,DMA_PAGE		;
	MOV	CX,0FFH 		; DO ALL DATA PATTERNS
C22A:	OUT	DX,AL			;
	INC	DX			;
	INC	AL			;
	CMP	DX,8FH			; TEST DMA PAGES 81 THRU 8EH
	JNZ	C22A			;
	XCHG	AH,AL			; SAVE CURRENT DATA PATTERN
	DEC	AH			; CHECK LAST WRITTEN
	DEC	DX			;
C22B:	SUB	AL,AL			; CHANGE DATA BEFORE READ
	IN	AL,DX			;
	CMP	AL,AH			; DATA AS WRITTEN?
	JNZ	C26			; GO ERROR HALT IF NOT
	DEC	AH			;
	DEC	DX			;
	CMP	DX,MFG_PORT		; CONTINUE TILL PORT 80
	JNZ	C22B			;
	INC	AH			; NEXT PATTERN TO RIPPLE
	MOV	AL,AH			;
	LOOP	C22A			;

;-------- TEST LAST DMA PAGE REGISTER (USED FOR ADDRESS LINES DURING REFRESH)

	MOV	AL,0CCH 		; WRITE AN CC TO PAGE REGISTERS
C22:	MOV	DX,LAST_DMA_PAGE	;
	MOV	AH,AL			; SAVE THE DATA PATTERN
C23:	OUT	DX,AL			; OUTPUT PAGE REG
;-------- VERIFY PAGE REGISTER 8F

C24:	SUB	AL,AL			; CHANGE DATA PATTERN BEFORE READ
	IN	AL,DX			; GET THE DATA FROM PAGE REG
	CMP	AL,AH			;
	JNZ	C26			; GO IF ERROR
	CMP	AH,0CCH 		;
	JNZ	C25			; GO IF ERROR
	MOV	AL,033H 		; SET UP DATA PATTERN OF 33
	JMP	C22			; DO DATA 33
C25:	CMP	AH,0			; CHECK DONE
	JZ	C27			; GO IF YES
	SUB	AL,AL			; SET UP FOR DATA PATTERN 00
	JMP	C22			; DO DATA 0

;------- ERROR HALT

C26:	HLT				; HALT SYSTEM
;--------------------------------------------------------
; TEST.09						:
;	STORAGE REFRESH TEST				:
; DESCRIPTION						:
;	VERIFY STORAGE REFRESH IS OCCURRING		:
;--------------------------------------------------------

;------- CHECKPOINT 9 TEST MEMORY REFRESH

C27:	MOV	AL,09H			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 9<><><>

	SUB	CX,CX
C28:	IN	AL,PORT_B		; INSURE REFRESH BIT IS TOGGLING
	TEST	AL,REFRESH_BIT		;
	LOOPZ	C28			; INSURE REFRESH IS OFF
	JZ	C26			; GO IF NOT
	SUB	CX,CX			;
C29:	IN	AL,PORT_B		;
	TEST	AL,REFRESH_BIT		; INSURE REFRESH IS ON
	LOOPNZ	C29			;
	JNZ	C26			; GO IF NO REFRESH
;-----------------------------------------------
; TEST.10				       :
;	8042 TEST AND CONFIGURATION JUMPERS    :
; DESCRIPTION				       :
;	ISSUE A SELF TEST TO THE 8042	       :
;	INSURE A 55H IS RECEIVED	       :
;	GET MANUFACTURING/DISPLAY TYPE JUMPER  :
;	 INPUT PORT INFO SAVED IN MFG_TEST     :
;-----------------------------------------------

;------- CHECKPOINT 0A

	MOV	AL,0AH			; <><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><>CHECPOINT 0A<><><>

;------- SOFT RESET (HANDLE ALL POSSIBLE CONDITIONS)

	SUB	CX,CX			; 100 MSEC FOR THIS LOOP
TST1:	IN	AL,STATUS_PORT		; CHECK FOR INPUT BUFFER FULL
	MOV	AH,AL			;
	TEST	AH,OUT_BUF_FULL 	;
	JZ	TST2			; GO IF NOT
	IN	AL,PORT_A		; FLUSH
TST2:	TEST	AH,INPT_BUF_FULL	; IS THE OUTPUT BUFFER ALSO FULL?
	LOOPNZ	TST1			; TRY AGAIN
	JZ	TST4			; CONTINUE IF OK

ERR0:	HLT				; HALT SYSTEM IF BUFFER FULL

;--------- ISSUE A RESET TO THE 8042

TST4:	MOV	AL,0BH			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 0B <><>

	MOV	AL,0AAH 		; SELF TEST COMMAND
	MOV	SP,OFFSET C8042A	; SET RETURN ADDR
	JMP	C8042			;
TST4_B: TEST	AL,OUT_BUF_FULL 	; IS THE OUTPUT BUFFER FULL?
	JZ	TST4_A			; GO IF NOT
	IN	AL,PORT_A		; FLUSH
TST4_A: MOV	SP,OFFSET OBF_42A	; SET RETURN ADDR
	JMP	OBF_42			; GO WAIT FOR BUFFER
TST4_C: IN	AL,PORT_A		; GET THE ENDING RESPONSE
	CMP	AL,55H			;

	MOV	AL,0CH			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 0C <><>

	JNZ	ERR0			; GO IF NOT OK

;------- GET THE SWITCH SETTINGS

	MOV	AL,READ_8042_INPUT	; READ INPUT COMMAND
	MOV	SP,OFFSET C8042C	; SET RETURN ADDRESS
	JMP	C8042			; ISSUE COMMAND
E30B:	MOV	SP,OFFSET OBF_42B	; SET RETURN ADDRESS
	JMP	OBF_42			; GO WAIT FOR RESPONSE
E30C:	IN	AL,PORT_A		; GET THE SWITCH
	OUT	DMA_PAGE+1,AL		; SAVE TEMP

;------ WRITE BYTE 0 OF 8042 RAM

	MOV	AL,60H			; WRITE BYTE COMMAND
	MOV	SP,OFFSET C8042B	; SET RETURN ADDR
	JMP	C8042			; ISSUE THE COMMAND
TST4_D: JZ	TST4_D1 		; CONTINUE IF COMMAND ACCEPTED

	MOV	AL,0DH			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 0D <><>
	HLT
TST4_D1:MOV	AL,5DH			; ENABLE OUTPUT BUFF FULL INT - DISABLE KEYBOARD
	OUT	PORT_A,AL		; SET SYS FLAG - PC 1 COMP - INH OVERRIDE
	JMP	E30A			; CONTINUE

;--------- ISSUE THE COMMAND TO THE 8042

C8042:	CLI				; NO INTERRUPTS ALLOWED
	OUT	STATUS_PORT,AL		; SEND COMMAND IN AL REG

	SUB	CX,CX			; LOOP COUNT
C42_1:	IN	AL,STATUS_PORT		; WAIT FOR THE COMMAND ACCEPTED
	TEST	AL,INPT_BUF_FULL	;
	LOOPNZ	C42_1
	RET				;

;------- WAIT FOR 8042 RESPONSE

OBF_42: SUB	CX,CX			;
	MOV	BL,6			; 200MS/PER LOOP * 6 =1200 MS +
C42_2:	IN	AL,STATUS_PORT		; CHECK FOR RESPONSE
	TEST	AL,OUT_BUF_FULL 	;
	JNZ	C42_3			; GO IF RESPONSE
	LOOP	C42_2			; TRY AGAIN
	DEC	BL			; DECREMENT LOOP COUNT
	JNZ	C42_2			;
C42_3:	RET				; RETURN TO CALLER
;------------------------------------------------
; TEST.11					:
;	BASE 64K READ/WRITE STORAGE TEST	:
; DESCRIPTION					:
;	WRITE/READ/VERIFY DATA PATTERNS 	:
;	AA,55,FF,01, AND 00 TO 1ST 64K OF	:
;	STORAGE, VERIFY STORAGE ADDRESSABILITY. :
;------------------------------------------------

;----- FILL MEMORY WITH DATA

E30A:	MOV	AL,0EH			;SET CHECKPOINT (E)
	OUT	MFG_PORT,AL		;<><><><><><><><><><><>

	MOV	AX,DATA 		; GET THE SYSTEM SEGMENT
	MOV	DS,AX			;  OF DATA
	MOV	BX,RESET_FLAG		; SAVE RESET_FLAG IN BX
	CLD				; SET DIR FLAG TO INC.
	MOV	CX,2000H*4		; SET FOR 32K WORDS
	SUB	DI,DI			; FIRST 16K
	SUB	SI,SI			;
	SUB	AX,AX			;
	MOV	DS,AX			;
	MOV	ES,AX			;
	CMP	BX,1234H		; WARM START?
	JNZ	E30A_0			; GO IF NOT
	JMP	CLR_STG

;-------- GET THE INPUT BUFFER (SWITCH SETTINGS)

E30A_0: MOV	AL,0FH			; <><><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><> CHECKPOINT F <><><>

	MOV	AL,PRTY_CHK		; SET BASE RAM PARITY
	OUT	DMA_PAGE+6,AL		; USE AS TEMP SAVE
	MOV	SP,OFFSET C2		; SET RETURN ADDRESS
	JMP	STGTST_CNT
C30:	MOV	BX,AX			; SAVE FAILING BIT PATTERN
	JNZ	C31
	JMP	C33			; STORAGE OK, CONTINUE
;-------------------------------------------
; BASE 64K STORAGE FAILURE
;   DISPLAY THE CHECKPOINT (MFG CHECKPOINT)
;     AND XOR EXPECTED WITH READ IN MFG_PORT
;   DISPLAY CHECKPOINT IN MFG_PORT+3
;   DISPLAY XOR'D DATA HIGH BYTE MFG_PORT+1
;     LOW BYTE IN MFG_PORT+2
;   A READ/WRITE SCOPE LOOP OF THE FIRST
;   WORD FOR POSSIBLE ADDRESS LINE FAILURES
;-------------------------------------------

C31:
	MOV	AL,BH			; SAVE HIGH BYTE
	OUT	MFG_PORT+1,AL		;
	MOV	AL,BL			; SAVE LOW BYTE
	OUT	MFG_PORT+2,AL

;------- CHECK FOR VIDEO ROM

	MOV	CX,0C000H		; START OF IO ROM
M1:	MOV	DS,CX			;
	SUB	BX,BX			; GET THE FIRST 2 LOCATIONS
	MOV	AX,[BX] 		;
	JMP	SHORT $+2		; BUS SETTLE
	CMP	AX,0AA55H		; IS THE VIDEO ROM PRESENT?
	JZ	Z5			; GO IF YES
	ADD	CX,080H 		; POINT TO NEXT 2K BLOCK
	CMP	CX,0C800H		; TOP OF VIDEO ROM AREA YET?
	JL	M1			; TRY AGAIN
	AND	CX,CX			; SET NON ZERO FLAG

Z5:	JNZ	C32			; GO IF NOT
	JMP	C31_0			; BYPASS ERROR DISPLAY IF VIDEO ROM
;-------------------------------------------------
; SET VIDEO MODE TO DISPLAY MEMORY ERROR
;	THIS ROUTINE INITIALIZES THE ATTACHMENT TO
;	TO DISPLAY FIRST 64K STORAGE ERRORS.
; BOTH COLOR AND MONO ATTACHMENTS ARE INITIALIZED.
;-------------------------------------------------
M4	EQU	10H
;------- INIT COLOR/MONO

C32:	MOV	DX,3D8H 		; CONTROL REG ADDRESS OF COLOR CARD
	SUB	AL,AL			; MODE SET
	OUT	DX,AL			;

	MOV	DX,03B8H		; CONTROL REG ADDRESS OF BW CARD
	MOV	AL,1			; MODE SET FOR CARD
	OUT	DX,AL			; RESET VIDEO
	SUB	DX,4			; BACK TO BASE REGISTER


	MOV	BX,OFFSET VIDEO_PARMS+M4*3  ; POINT TO VIDEO PARMS
	ASSUME	DS:CODE
Z_2:	MOV	CX,M4			; COUNT OF MONO VIDEO PARMS

;----- BX POINTS TO CORRECT ROW OF INITIALIZATION TABLE

	XOR	AH,AH		; AH WILL SERVE AS REGISTER NUMBER DURING LOOP

;----- LOOP THROUGH TABLE, OUTPUTTING REG ADDRESS, THEN VALUE FROM TABLE

M10:	MOV	AL,AH			; GET 6845 REGISTER NUMBER
	OUT	DX,AL
	INC	DX			; POINT TO DATA PORT
	INC	AH			; NEXT REGISTER VALUE
	MOV	AL,CS:[BX]		; GET TABLE VALUE
	OUT	DX,AL			; OUT TO CHIP
	INC	BX			; NEXT IN TABLE
	DEC	DX			; BACK TO POINTER REGISTER
	LOOP	M10			; DO THE WHOLE TABLE
	MOV	AH,DL			; CHECK IF COLOR CARD DONE
	AND	AH,0F0H 		; STRIP UNWANTED BITS
	CMP	AH,0D0H 		; IS IT THE COLOR CARD?
	JZ	Z_3			; CONTINUE IF COLOR
	MOV	BX,OFFSET VIDEO_PARMS	; POINT TO VIDEO PARMS
	MOV	DX,3D4H 		; COLOR BASE
	JMP	Z_2			; CONTINUE

;------ FILL REGEN AREA WITH BLANK

Z_3:	XOR	DI,DI			; SET UP POINTER FOR REGEN
	MOV	AX,0B000H		; SET UP ES TO VIDEO REGEN
	MOV	ES,AX			;

	MOV	CX,2048 		; NUMBER OF WORDS IN MONO CARD
	MOV	AX,' '+7*256            ; FILL CHAR FOR ALPHA
	REP	STOSW			; FILL THE REGEN BUFFER WITH BLANKS

	XOR	DI,DI			; CLEAR COLOR VIDEO RAM
	MOV	BX,0B800H		; SET UP ES TO COLOR VIDEO RAM
	MOV	ES,BX			;
	MOV	CX,8192 		;
	REP	STOSW			; FILL WITH BLANKS

;----- ENABLE VIDEO AND CORRECT PORT SETTING

	MOV	DX,3B8H
	MOV	AL,29H			;
	OUT	DX,AL			; SET VIDEO ENABLE PORT

;----- SET UP OVERSCAN REGISTER

	INC	DX			; SET OVERSCAN PORT TO A DEFAULT
	MOV	AL,30H			; VALUE OF 30H FOR ALL MODES EXCEPT 640X200
	OUT	DX,AL			; OUTPUT THE CORRECT VALUE TO 3D9 PORT

;----- ENABLE COLOR VIDEO AND CORRECT PORT SETTING
	MOV	DX,3D8H
	MOV	AL,28H			;
	OUT	DX,AL			; SET VIDEO ENABLE PORT

;----- SET UP OVERSCAN REGISTER

	INC	DX			; SET OVERSCAN PORT TO A DEFAULT
	MOV	AL,30H			; VALUE OF 30H FOR ALL MODES EXCEPT 640X200
	OUT	DX,AL			; OUTPUT THE CORRECT VALUE TO 3D9 PORT

;------- DISPLAY FAILING CHECKPOINT AND

	MOV	AX,CS			; SET STACK SEGMENT TO CODE SEGMENT
	MOV	SS,AX			;

	MOV	BX,0B000H		;
	MOV	DS,BX			; SET DS TO BW CRT BUFFER

Z_0:	MOV	AL,'0'                  ; DISPLAY BANK 000000
	MOV	CX,6			;
	SUB	DI,DI			; START AT 0
Z:	MOV	DS:[DI],AL		; WRITE TO CRT BUFFER
	INC	DI			; POINT TO NEXT POSITION
	INC	DI			;
	LOOP	Z

	CMP	BH,0B8H 		; CHECK THAT COLOR BUFFER WRITTEN
	JZ	Z_1
	SUB	DI,DI			; POINT TO START OF BUFFER

	MOV	BH,0B0H 		;
	MOV	ES,BX			; ES = MONO
	MOV	BH,0B8H 		; SET SEGMENT TO COLOR
	MOV	DS,BX			; DS = COLOR
	JMP	Z_0

;------- PRINT FAILING BIT PATTERN

Z_1:	MOV	AL,' '                  ; DISPLAY A BLANK
	MOV	DS:[DI],AL		; WRITE TO COLOR BUFFER
	MOV	ES:[DI],AL		; WRITE TO MONO BUFFER
	INC	DI			; POINT TO NEXT POSITION
	INC	DI			;
	IN	AL,MFG_PORT+1		; GET THE HIGH BYTE OF FAILING PATTERN
	MOV	CL,4			; SHIFT COUNT
	SHR	AL,CL			; NIBBLE SWAP
	MOV	SP,OFFSET Z1_0
	JMP	PR

Z1:	IN	AL,MFG_PORT+1		;
	AND	AL,0FH			; ISOLATE TO LOW NIBBLE
	MOV	SP,OFFSET Z2_0
	JMP	PR
Z2:	IN	AL,MFG_PORT+2		; GET THE HIGH BYTE OF FAILING PATTERN
	MOV	CL,4			; SHIFT COUNT
	SHR	AL,CL			; NIBBLE SWAP
	MOV	SP,OFFSET Z3_0
	JMP	PR
Z3:	IN	AL,MFG_PORT+2		;
	AND	AL,0FH			; ISOLATE TO LOW NIBBLE
	MOV	SP,OFFSET Z4_0		; RETURN TO Z4:

;------- CONVERT AND PRINT
					;	CONVERT 00-0F TO ASCII CHARACTER
PR:	ADD	AL,090H 		; ADD FIRST CONVERSION FACTOR
	DAA				; ADJUST FOR NUMERIC AND ALPHA RANGE
	ADC	AL,040H 		; ADD CONVERSION AND ADJUST LOW NIBBLE
	DAA				; ADJUST HIGH NIBBLE TO ASCII RANGE

	MOV	DS:[DI],AL		; WRITE TO COLOR BUFFER
	MOV	ES:[DI],AL		; WRITE TO MONO BUFFER
	INC	DI			; POINT TO NEXT POSITION
	INC	DI			;
	RET

;------- DISPLAY 201 ERROR

Z4:	MOV	AL,' '                  ; DISPLAY A BLANK
	MOV	DS:[DI],AL		; WRITE TO CRT BUFFER
	MOV	ES:[DI],AL		; WRITE TO MONO BUFFER
	INC	DI			; POINT TO NEXT POSITION
	INC	DI			;
	MOV	AL,'2'                  ; DISPLAY 201 ERROR
	MOV	DS:[DI],AL		; WRITE TO CRT BUFFER
	MOV	ES:[DI],AL		; WRITE TO MONO BUFFER
	INC	DI			; POINT TO NEXT POSITION
	INC	DI			;
	MOV	AL,'0'                  ;
	MOV	DS:[DI],AL		; WRITE TO CRT BUFFER
	MOV	ES:[DI],AL		; WRITE TO MONO BUFFER
	INC	DI			; POINT TO NEXT POSITION
	INC	DI			;
	MOV	AL,'1'                  ;
	MOV	DS:[DI],AL		; WRITE TO CRT BUFFER
	MOV	ES:[DI],AL		; WRITE TO MONO BUFFER

;-------- ROLL ERROR CODE IN MFG_PORT --> FIRST THE CHECKPOINT

C31_0:	MOV	AL,0DDH 		; <><><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT DD <><><>
	OUT	MFG_PORT+3,AL		; ALSO DISPLAY CHECK POINT IN PORT 83
	SUB	CX,CX			;
C31_A:

	SUB	AX,AX			; SETUP SEGMENT
	MOV	DS,AX			;
	MOV	AX,0AA55H		; WRITE AN AA55
	SUB	DI,DI			;
	MOV	DS:[DI],AX		;
	MOV	AX,DS:[DI]		; READ THE FIRST WORD
	LOOP	C31_A			; DISPLAY CHKPT LONGER
C31_B:
	MOV	DS:[DI],AX		;
	MOV	AX,DS:[DI]		;
	LOOP	C31_B
C31_C:
	MOV	DS:[DI],AX		;
	MOV	AX,DS:[DI]		;
	LOOP	C31_C			;
C31_D:
	MOV	DS:[DI],AX		;
	MOV	AX,DS:[DI]		;
	LOOP	C31_D			;
C31_E:
	MOV	DS:[DI],AX		;
	MOV	AX,DS:[DI]		;
	LOOP	C31_E

;-------- ROLL ERROR CODE IN MFG_PORT --> NEXT THE HIGH BYTE

	IN	AL,MFG_PORT+1		; XOR OF FAILING BIT PATTERN
	OUT	MFG_PORT,AL		;  HIGH BYTE
C31_G:
	MOV	AX,0AA55H		; WRITE AN AA55
	MOV	DS:[DI],AX		;
	MOV	AX,DS:[DI]		; READ THE FIRST WORD
	LOOP	C31_G			;
C31_H:
	MOV	DS:[DI],AX		;
	MOV	AX,DS:[DI]		;
	LOOP	C31_H			;
C31_I:
	MOV	DS:[DI],AX		;
	MOV	AX,DS:[DI]		;
	LOOP	C31_I

;-------- ROLL ERROR CODE IN MFG_PORT --> THEN THE LOW BYTE

	IN	AL,MFG_PORT+2		;  LOW BYTE
	OUT	MFG_PORT,AL		;
	MOV	AX,0AA55H		; WRITE AN AA55
C31_K:	SUB	DI,DI			;
	MOV	DS:[DI],AX		;
	MOV	AX,DS:[DI]		; READ THE FIRST WORD
	LOOP	C31_K			;
C31_L:
	MOV	DS:[DI],AX		;
	MOV	AX,DS:[DI]		;
	LOOP	C31_L			;
C31_M:
	MOV	DS:[DI],AX		;
	MOV	AX,DS:[DI]		;
	LOOP	C31_M
C31_N:
	MOV	DS:[DI],AX		;
	MOV	AX,DS:[DI]		;
	LOOP	C31_N			;
	JMP	C31_0			; DO AGAIN

Z1_0	DW	Z1			; TEMP STACK
Z2_0	DW	Z2			; TEMP STACK
Z3_0	DW	Z3			; TEMP STACK
Z4_0	DW	Z4			; TEMP STACK

;------- CLEAR STORAGE ENTRY

CLR_STG:
	ASSUME	DS:DATA
	REP	STOSW			; STORE 32K WORDS OF 0000
	MOV	AX,DATA 		; RESTORE DATA SEGMENT
	MOV	DS,AX			;
	MOV	RESET_FLAG,BX		; RESTORE RESET FLAG

;----- SETUP STACK SEG AND SP

C33:	MOV	AX,DATA 		; SET DATA SEGMENT
	MOV	DS,AX			;
	MOV	SP,POST_SS		; GET STACK VALUE
	MOV	SS,SP			; SET THE STACK UP
	MOV	SP,POST_SP		; STACK IS READY TO GO

;-------- GET THE INPUT BUFFER (SWITCH SETTINGS)

C37:	MOV	AL,11H			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 11 <><>

	IN	AL,DMA_PAGE+1		; GET THE SWITCH SETTINGS
	AND	AL,0F0H 		; STRIP UNUSED BITS
	MOV	MFG_TST,AL		; SAVE SETTINGS
	SUB	AL,AL			; RESET DMA_PAGE
	OUT	DMA_PAGE+1,AL		;
;------------------------------------------------
; TEST.11A					:
;	VERIFY 286 LGDT/SGDT LIDT/SIDT		:
;	INSTRUCTIONS				:
; DESCRIPTION					:
;	LOAD GDT AND IDT REGISTERS WITH 	:
;	AA,55,00 AND VERIFY CORRECT		:
;------------------------------------------------

;-------- VERIFY STATUS INDICATE COMPABILITY (REAL) MODE

	SMSW	AX			; GET THE CURRENT STATUS WORD
	TEST	AX,0FH			; PE/MP/EM/TS BITS SHOULD BE ZERO
	JNZ	ERR_PROT		; GO IF STATUS NOT REAL MODE

;-------- TEST PROTECTED MODE REGISTERS

	MOV	AL,12H			;SET CHECK POINT 12
	OUT	MFG_PORT,AL		;<><><><><><><><><><><>

	PUSH	DS			; SET ES TO SAME SEGMENT AS DS
	POP	ES			;
	MOV	DI,SYS_IDT_LOC		; USE THIS AREA TO BUILD TEST PATTERN
	MOV	CX,3			;
	MOV	AX,0AAAAH		; FIRST PATTERN
	CALL	WRT_PAT 		;
	MOV	AX,05555H		;
	CALL	WRT_PAT 		; WRITE NEXT PATTERN
	SUB	AX,AX			; WRITE 0
	CALL	WRT_PAT 		;
	SUB	BP,BP			; RESTORE BP REG

;-------- TEST 286 CONTROL FLAGS

	STD				; SET DIRECTION FLAG FOR DECREMENT
	PUSHF				; GET THE FLAGS
	POP	AX			;
	TEST	AX,0200H		; INTERRUPT FLAG SHOULD BE OFF
	JNZ	ERR_PROT		; GO IF NOT
	TEST	AX,0400H		; CHECK DIRECTION FLAG
	JZ	ERR_PROT		; GO IF NOT SET
	CLD				; CLEAR DIRECTION FLAG
	PUSHF				; INSURE DIRECTION FLAG IS RESET
	POP	AX			;
	TEST	AX,0400H		;
	JNZ	ERR_PROT		; GO IF NOT

	JMP	C37A			; TEST OK CONTINUE
ERR_PROT:
	HLT				; PROTECTED MODE REGISTER FAILURE
	JMP	SHORT ERR_PROT		; INSURE NO BREAKOUT OF HALT

;------- WRITE TO 286 REGISTERS

WRT_PAT:MOV	CX,3			;
	REP	STOSW			; STORE 6 BYTES OF PATTERN
	MOV	BP,SYS_IDT_LOC		;
	SEGOV	ES			; LOAD THE IDT
	LIDT	[BP]			;  REGISTER FROM THIS AREA
	MOV	BP,SYS_IDT_LOC		;
	SEGOV	ES			; LOAD THE GDT
	LGDT	[BP]			;  FROM THE SAME AREA
;------- READ AND VERIFY 286 REGISTERS

	MOV	BP,GDT_LOC		; STORE THE REGISTERS HERE
	SEGOV	ES
	SIDT	[BP]			; GET THE IDT REGS
	MOV	BP,GDT_LOC+5		;
	SEGOV	ES			;
	SGDT	[BP]			; GET THE GDT REGS
	MOV	DI,SYS_IDT_LOC		;
	MOV	AX,[DI] 		; GET THE PATTERN WRITTEN
	MOV	CX,5			; CHECK ALL REGISTERS
	MOV	SI,GDT_LOC		; POINT TO THE BEGINNING
C37B:	CMP	AX,ES:[SI]		;
	JNZ	ERR_PROT		; HALT IF ERROR
	INC	SI			; POINT TO NEXT WORD
	INC	SI			;
	LOOP	C37B			; CONTINUE TILL DONE
	RET
;--------------------------------------------------------
;	INITIALIZE THE 8259 INTERRUPT #1 CONTROLLER CHIP :
;--------------------------------------------------------

C37A:	SUB	AL,AL			; RESET MATH PROCESSOR
	OUT	X287+1,AL		;
	MOV	AL,11H			; ICW1 - EDGE, MASTER, ICW4
	OUT	INTA00,AL
	JMP	SHORT $+2		; WAIT STATE FOR IO
	MOV	AL,8			; SETUP ICW2 - INT TYPE 8 (8-F)
	OUT	INTA01,AL
	JMP	SHORT $+2		; WAIT STATE FOR IO

	MOV	AL,04H			; SETUP ICW3 - MASTER LV 2
	OUT	INTA01,AL		;
	JMP	SHORT $+2		; IO WAIT STATE
	MOV	AL,01H			; SETUP ICW4 - MASTER,8086 MODE
	OUT	INTA01,AL		;
	JMP	SHORT $+2		; WAIT STATE FOR IO
	MOV	AL,0FFH 		; MASK ALL INTS. OFF
	OUT	INTA01,AL		; (VIDEO ROUTINE ENABLES INTS.)

;---------------------------------------------------------
;	INITIALIZE THE 8259 INTERRUPT #2 CONTROLLER CHIP  :
;---------------------------------------------------------

	MOV	AL,13H			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 13 <><>

	MOV	AL,11H			; ICW1 - EDGE, SLAVE ICW4
	OUT	INTB00,AL
	JMP	SHORT $+2		; WAIT STATE FOR IO
	MOV	AL,INT_TYPE		; SETUP ICW2 - INT TYPE 70 (70-7F)
	OUT	INTB01,AL		;
	MOV	AL,02H			; SETUP ICW3 - SLAVE LV 2
	JMP	SHORT $+2		;
	OUT	INTB01,AL		;
	JMP	SHORT $+2		; IO WAIT STATE
	MOV	AL,01H			; SETUP ICW4 - 8086 MODE, SLAVE
	OUT	INTB01,AL
	JMP	SHORT $+2		; WAIT STATE FOR IO
	MOV	AL,0FFH 		; MASK ALL INTS. OFF
	OUT	INTB01,AL		;
;------- SET UP THE INTERRUPT VECTORS TO TEMP INTERRUPT

	MOV	AL,14H			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 14 <><>

	MOV	CX,78H			; FILL ALL INTERRUPT LOCATIONS
	SUB	DI,DI			; FIRST INTERRUPT LOCATION
	MOV	ES,DI			; SET ES ALSO
D3:	MOV	AX,OFFSET D11		; MOVE ADDRESS OF INT OFFSET
	STOSW
	MOV	AX,CS			; GET THE SEGMENT
	STOSW
	LOOP	D3			;

;------- ESTABLISH BIOS SUBROUTINE CALL INTERRUPT VECTORS

	MOV	AL,15H			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 15 <><>


	MOV	DI,OFFSET VIDEO_INT	; SET VIDEO INT AREA
	PUSH	CS			;
	POP	DS			; SET UP ADDRESS OF VECTOR TABLE
	MOV	AX,DS			; SET AX=SEGMENT
	MOV	SI,OFFSET VECTOR_TABLE+16 ; START WITH VIDEO ENTRY
	MOV	CX,16			;

D3A:	MOVSW				; MOVE VECTOR TABLE TO RAM
	INC	DI
	INC	DI			; SKIP SEGMENT POINTER
	LOOP	D3A

;-------------------------------------------------
; TEST.12					 :
;	VERIFY CMOS CHECKSUM/BATTERY GOOD	 :
; DESCRIPTION					 :
;	DETERMINE IF CONFIG RECORD SHOULD BE	 :
;	USED FOR INITIALIZATION 		 :
;-------------------------------------------------
	ASSUME	DS:DATA
CMOS:	CALL	DDS			; SET THE DATA SEGMENT

	MOV	AL,16H			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 16 <><>

;------- IS THE BATTERY LOW THIS POWER UP?

	MOV	AL,BATTERY_COND_STATUS	; CHECK BATTERY CONDITION
	OUT	CMOS_PORT,AL		;  POINT TO BATTERY STATUS
	JMP	SHORT $+2		; WAIT STATE FOR IO
	IN	AL,CMOS_PORT+1		;
	TEST	AL,80H			; IS THE BATTERY LOW?
	JZ	CMOS1A			; GO IF YES
	MOV	AL,DIAG_STATUS		; GET THE OLD STATUS
	OUT	CMOS_PORT,AL		;
	JMP	SHORT $+2		;
	IN	AL,CMOS_PORT+1		;
	TEST	AL,BAD_BAT		; HAS CUSTOMER SETUP BEEN EXECUTED?
	JZ	CMOS1			; GO CHECK CHECKSUM IF YES

	JMP	CMOS4			; CONTINUE WITHOUT CONFIG

;------ SET DEFECTIVE BATTERY FLAG

CMOS1A: MOV	AL,17H			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 17 <><>

	MOV	AL,DIAG_STATUS		; CMOS DIAGNOSTIC STATUS BYTE
	OUT	CMOS_PORT,AL		;
	JMP	SHORT $+2		;
	IN	AL,CMOS_PORT+1		; GET THE CURRENT STATUS
	XCHG	AL,AH			; SAVE
	OR	AH,BAD_BAT		; SET THE DEAD BATTERY FLAG
	MOV	AL,DIAG_STATUS		;
	OUT	CMOS_PORT,AL		;
	XCHG	AL,AH			; OUTPUT THE STATUS
	JMP	SHORT $+2		;
	OUT	CMOS_PORT+1,AL		; SET FLAG IN CMOS
	JMP	CMOS4			; GO TO MINIMUM CONFIG
;----- VERIFY CHECKSUM

CMOS1:	MOV	AL,DIAG_STATUS		; CLEAR OLD STATUS
	OUT	CMOS_PORT,AL		;
	JMP	SHORT $+2		; IO DELAY
	IN	AL,CMOS_PORT+1		; GET THE CURRENT STATUS
	JMP	SHORT $+2		; IO DELAY
	XCHG	AL,AH			; SAVE THE CURRENT STATUS
	MOV	AL,DIAG_STATUS		;
	OUT	CMOS_PORT,AL		;
	CMP	RESET_FLAG,1234H	; IS THIS A SOFT RESET
	JNZ	CMOS1_A 		; GO IF NOT
	XCHG	AH,AL			; RESTORE THE STATUS
	AND	AL,W_MEM_SIZE		; CLEAR ALL BUT THE CMOS/POR MEMORY SIZE
					;   MISCOMPARE
	JMP	CMOS1_B 		;

CMOS1_A:
	SUB	AL,AL			;
CMOS1_B:OUT	CMOS_PORT+1,AL		;

	SUB	BX,BX
	SUB	CX,CX			;
	MOV	CL,CMOS_BEGIN		; SET START OF CMOS
	MOV	CH,CMOS_END+1		; SET END OF CMOS

CMOS2:	MOV	AL,CL			;
	OUT	CMOS_PORT,AL		; ADDRESS THE BEGINNING
	JMP	SHORT $+2		; WAIT STATE FOR IO
	IN	AL,CMOS_PORT+1		;
	SUB	AH,AH			; INSURE AH=0
	ADC	BX,AX			; ADD TO CURRENT VALUE
	INC	CL			; POINT TO NEXT WORD
	CMP	CH,CL			; FINISHED?
	JNZ	CMOS2			; GO IF NOT
	OR	BX,BX			; BX MUST NOT BE 0
	JZ	CMOS3			; CMOS BAD IF CKSUM=0
	MOV	AL,CMOS_END+1		; GET THE CHECK SUM
	OUT	CMOS_PORT,AL		;
	JMP	SHORT $+2		;
	IN	AL,CMOS_PORT+1		; FIRST BYTE OF CHECKSUM
	MOV	AH,AL			; SAVE IT
	MOV	AL,CMOS_END+2		; SECOND BYTE OF CHECKSUM
	OUT	CMOS_PORT,AL		;
	JMP	SHORT $+2		;
	IN	AL,CMOS_PORT+1		;
	CMP	AX,BX			; IS THE CHECKSUM OK
	JZ	CMOS4			; GO IF YES

;------- SET CMOS CHECKSUM ERROR

CMOS3:	MOV	AL,DIAG_STATUS		; SET BAD CHECKSUM FLAG
	OUT	CMOS_PORT,AL		;
	JMP	SHORT $+2		; IO DELAY
	IN	AL,CMOS_PORT+1		; GET THE CURRENT STATUS
	XCHG	AL,AH			; SAVE IT
	OR	AH,BAD_CKSUM		; SET BAD CHECKSUM FLAG
	MOV	AL,DIAG_STATUS		;
	OUT	CMOS_PORT,AL		;
	JMP	SHORT $+2		; IO DELAY
	XCHG	AL,AH			; SET FLAG
	OUT	CMOS_PORT+1,AL		;
CMOS4:	MOV	AL,18H			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 18 <><>
;-------------------------------------------------------
;						       :
;	ENABLE PROTECTED MODE			       :
;						       :
;-------------------------------------------------------
	IN	AL,PORT_B		; DISABLE IO/RAM PARITY CHK
	OR	AL,RAM_PAR_OFF		;
	JMP	SHORT $+2		; IO DELAY
	OUT	PORT_B,AL		;

;------- SET RETURN ADDRESS BYTE IN CMOS

	MOV	AL,19H			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 19 <><>

	MOV	AL,SHUT_DOWN		; SET THE RETURN ADDR
	OUT	CMOS_PORT,AL		;
	JMP	SHORT $+2		; IO DELAY
	MOV	AL,01H			; FIRST SHUTDOWN RETN ADDR
	OUT	CMOS_PORT+1,AL		;

	MOV	SP,POST_SS		; SET STACK FOR SYSINIT1
	MOV	SS,SP			;
	MOV	SP,POST_SP		;
	CALL	SYSINIT1		; CALL THE DESCRIPTOR TABLE BUILDER
					;  AND REAL-TO-PROTECTED MODE SWITCHER

	MOV	AL,1AH			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 1A <><>

;-------- SET TEMPORY STACK

	MOV	AX,GDT_PTR		;
	MOV	DS,AX			;
	MOV	DS:SS_TEMP.BASE_LO_WORD,0
	MOV	BYTE PTR DS:(SS_TEMP.BASE_HI_BYTE),TEMP_STACK_HI
	MOV	SI,SS_TEMP		;
	MOV	SS,SI			;
	MOV	SP,MAX_SEG_LEN-2	;
;--------------------------------------------
; TEST.13				    :
;  PROTECTED MODE TEST			    :
;    CHECK MSW FOR PROTECTED MODE	    :
;  MEMORY SIZE DETERMINE (RAM -> 640K)	    :
; DESCRIPTION				    :
;  THIS ROUTINE RUNS IN PROTECTED MODE IN   :
;  ORDER TO ADDRESS ALL STORAGE 	    :
; MEMORY SIZE IS SAVED AT MEMORY_SIZE	    :
; CMOS DIAGNOSTIC BYTE BIT 4 = 512 -> 640K  :
;--------------------------------------------

;------- INSURE PROTECTED MODE

	SMSW	AX				; GET THE MACHINE STATUS WORD
	TEST	AX,VIRTUAL_ENABLE		; ARE WE IN PROTECTED MODE
	JNZ	VIR_OK

SHUT_8: MOV	AL,SHUT_DOWN			; SET THE RETURN ADDR
	OUT	CMOS_PORT,AL			;
	JMP	SHORT $+2			; IO DELAY
	MOV	AL,08H				; SET SHUTDOWN 8
	OUT	CMOS_PORT+1,AL			;
	JMP	PROC_SHUTDOWN			; CAUSE A SHUTDOWN

;-------- VIRTUAL MODE ERROR HALT

SHUT8:	HLT
	JMP	SHUT8				; ERROR HALT


;------- 64K SEGMENT LIMIT

VIR_OK: MOV	DS:ES_TEMP.SEG_LIMIT,MAX_SEG_LEN

;------- CPL0, DATA ACCESS RIGHTS

	MOV	BYTE PTR DS:(ES_TEMP.DATA_ACC_RIGHTS),CPL0_DATA_ACCESS

;------- START WITH SEGMENT ADDR 01-0000 (SECOND 64K)

	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),01H
	MOV	DS:ES_TEMP.BASE_LO_WORD,0H

	MOV	AL,1BH			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 1B <><>

	MOV	BX,16*4 		; SET THE FIRST 64K DONE


;------- START STORAGE SIZE/CLEAR

NOT_DONE:
	MOV	AX,ES_TEMP		; POINT ES TO DATA
	MOV	ES,AX			; POINT TO SEGMENT TO TEST
	CALL	HOW_BIG 		; DO THE FIRST 64K
	JZ	NOT_FIN 		; CHECK IF TOP OF RAM
	JMP	DONE			;

NOT_FIN:
	ADD	BX,16*4 		; BUMP MEMORY COUNT BY 64K

;------- DO NEXT 64K (0X0000) BLOCK

	INC	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE)

;------- CHECK FOR END OF FIRST 640K (END OF BASE RAM)

	CMP	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),0AH
	JNZ	NOT_DONE				      ; GO IF NOT
	CALL	HOW_BIG_END				      ; GO SET MEMORY SIZE
	JMP	DONE

;------- FILL/CHECK LOOP

HOW_BIG:
	SUB	DI,DI
	MOV	AX,0AA55H		; TEST PATTERN
	MOV	CX,AX			; SAVE PATTERN
	MOV	ES:[DI],AX		; SEND PATTERN TO MEM.
	MOV	AL,0FH			; PUT SOMETHING IN AL
	MOV	AX,ES:[DI]		; GET PATTERN
	MOV	ES:[DI],AX		; INSURE NO PARITY IO CHECK
	XOR	AX,CX			; COMPARE PATTERNS
	JNZ	HOW_BIG_END		; GO END IF NO COMPARE

	PUSH	DS			;
	MOV	AX,RSDA_PTR		; POINT TO SYSTEM DATA AREA
	MOV	DS,AX			;
	CMP	RESET_FLAG,1234H	; SOFT RESET
	POP	DS			; RESTORE DS
	JNZ	HOW_BIG_2		; GO IF NOT SOFT RESET

	MOV	WORD PTR ES:[DI],0101H	; TURN OFF BOTH PARITY BITS

	IN	AL,PORT_B
	JMP	SHORT $+2		; IO DELAY
	OR	AL,RAM_PAR_OFF		; TOGGLE PARITY CHECK ENABLES
	OUT	PORT_B,AL
	JMP	SHORT $+2		; IO DELAY
	AND	AL,RAM_PAR_ON
	OUT	PORT_B,AL

	MOV	AX,0FFFFH
	PUSH	AX
	POP	AX			; DELAY
	MOV	AX,ES:[DI]		; CHECK PARITY

	IN	AL,PORT_B		; CHECK FOR PARITY/IO CHECK
	AND	AL,PARITY_ERR		;

	MOV	WORD PTR ES:[DI],0	; INSURE NO PARITY/IO CHECK
	JNZ	HOW_BIG_END		; GO IF PARITY/IO CHECK
HOW_BIG_2:
	SUB	AX,AX			; WRITE ZEROS

	MOV	CX,2000H*4		; SET COUNT FOR 32K WORDS
	REP	STOSW			; FILL 32K WORDS
	RET				;

HOW_BIG_END:
	PUSHF				; SAVE THE CURRENT FLAGS
	MOV	AL,1CH			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><>CHECKPOINT 1C <><><>

;-------- SET OR RESET 512 TO 640 INSTALLED FLAG

	MOV	AL,INFO_STATUS		; SET/RESET 640K STATUS FLAG
	OUT	CMOS_PORT,AL		;
	JMP	SHORT $+2		; IO DELAY
	IN	AL,CMOS_PORT+1		; GET THE DIAGNOSTIC STATUS
	OR	AL,M640K		;
	XCHG	AL,AH			; SAVE THE STATUS
	MOV	AL,INFO_STATUS		;
	OUT	CMOS_PORT,AL		;
	XCHG	AL,AH			; RESTORE THE STATUS
	CMP	BX,512			; CHECK MEMORY SIZE
	JA	K640			; SET FLAG FOR 512 -> 640 INSTALLED
	AND	AL,NOT M640K		;
K640:	OUT	CMOS_PORT+1,AL		;
	MOV	AX,RSDA_PTR		; RESTORE THE DATA SEGMENT
	MOV	DS,AX			;
	MOV	MEMORY_SIZE,BX		; SAVE MEMORY SIZE
	POPF				; RESTORE THE FLAG REG
	RET
;--------------------------------------------
; TEST.13A				    :
;  MEMORY SIZE DETERMINE (RAM ABOVE 1024K)  :
; DESCRIPTION:				    :
;  THIS ROUTINE RUNS IN PROTECTED MODE	    :
; MEMORY SIZE ABOVE 1MEG ADDRESSING IS	    :
; SAVED IN CMOS 			    :
;--------------------------------------------

DONE:
	MOV	AX,GDT_PTR		; POINT DS TO THE DESCRIPTOR TABLE
	MOV	DS,AX

;------- START WITH SEGMENT ADDR 10-0000 (ONE MEG AND ABOVE)

	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),10H
	MOV	DS:ES_TEMP.BASE_LO_WORD,0H

	MOV	AL,1DH			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 1D <><>

	SUB	BX,BX			; START WITH COUNT 0

;------- START STORAGE SIZE/CLEAR

NOT_DONE1:
	MOV	AX,ES_TEMP		; POINT ES TO DATA
	MOV	ES,AX			; POINT TO SEGMENT TO TEST
	CALL	HOW_BIG1		; DO THE FIRST 64K

	JZ	DONEA			; CHECK IF TOP
	JMP	DONE1			; GO IF TOP

DONEA:	ADD	BX,16*4 		; BUMP MEMORY COUNT BY 64K

;------- DO NEXT 64K (XX0000) BLOCK

	INC	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE)

;------- CHECK FOR TOP OF RAM (FE0000)

NOT_END_BASE:
	CMP	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),0FEH 	; LAST OF POSSIBLE RAM?
	JNZ	NOT_DONE1					; GO IF NOT
	CALL	HOW_BIG_END1					; GO SET MEMORY SIZE
	JMP	DONE1
;------- FILL/CHECK LOOP

HOW_BIG1:
	SUB	DI,DI
	MOV	AX,0AA55H		; TEST PATTERN
	MOV	CX,AX			; SAVE PATTERN
	MOV	ES:[DI],AX		; SEND PATTERN TO MEM.
	MOV	AL,0FH			; PUT SOMETHING IN AL
	MOV	AX,ES:[DI]		; GET PATTERN
	MOV	ES:[DI],AX		; INSURE NO PARITY IO CHECK
	XOR	AX,CX			; COMPARE PATTERNS
	JNZ	HOW_BIG_END1		; GO END IF NO COMPARE

	PUSH	DS			;
	MOV	AX,RSDA_PTR		; POINT TO SYSTEM DATA AREA
	MOV	DS,AX			;
	CMP	RESET_FLAG,1234H	; SOFT RESET
	POP	DS			; RESTORE DS
	JNZ	HOW_BIG_2A		; GO IF NOT SOFT RESET

	MOV	WORD PTR ES:[DI],0101H	; TURN OFF BOTH PARITY BITS
	MOV	AX,0FFFFH		;
	PUSH	AX
	POP	AX			; DELAY
	MOV	AX,ES:[DI]		; CHECK PARITY
	IN	AL,PORT_B		; CHECK FOR IO CHECK
	TEST	AL,IO_CHK		;

	MOV	WORD PTR ES:[DI],0	; INSURE NO PARITY IO CHECK
	JNZ	HOW_BIG_END1		; GO IF IO CHECK
HOW_BIG_2A:
	SUB	AX,AX			; WRITE ZEROS
	MOV	CX,2000H*4		; SET COUNT FOR 32K WORDS
	REP	STOSW			; FILL 32K WORDS
	RET

HOW_BIG_END1:
	MOV	AL,1EH			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><>CHECKPOINT 1E <><><>

;------- SET IO RAM SIZE IN CMOS

	MOV	AL,M_SIZE_LO		;
	OUT	CMOS_PORT,AL		; ADDRESS LO BYTE
	JMP	SHORT $+2		; IO DELAY
	MOV	AL,BL			; SET LOW MEMORY SIZE
	OUT	CMOS_PORT+1,AL		;   IN CMOS
	JMP	SHORT $+2		; IO DELAY
	MOV	AL,M_SIZE_HI		; ADDRESS HI BYTE
	OUT	CMOS_PORT,AL		;
	JMP	SHORT $+2		; IO DELAY
	MOV	AL,BH			; SET THE HIGH MEMORY SIZE
	OUT	CMOS_PORT+1,AL		;   IN CMOS

	RET

;------- TEST ADDRESS LINES 19 - 23

DONE1:	MOV	AL,1FH			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 1F <><>
	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),00H
	MOV	DX,0FFFFH		; WRITE FFFF AT ADDRESS 0
	CALL	SD0			;
	SUB	DX,DX			; WRITE 0

	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),08H
	CALL	SD0			;
	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),10H
	CALL	SD0			;
	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),20H
	CALL	SD0			;
	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),40H
	CALL	SD0			;
	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),80H
	CALL	SD0			;

	JMP	SD2			; TEST PASSED CONTINUE

SD0:	SUB	DI,DI			;
	MOV	AX,ES_TEMP		; POINT ES TO DATA
	MOV	ES,AX			; POINT TO SEGMENT TO TEST
	MOV	ES:[DI],DX		; WRITE THE PATTERN

	MOV	BYTE PTR DS:(ES_TEMP.BASE_HI_BYTE),00H

	MOV	AX,ES_TEMP		; POINT ES TO DATA
	MOV	ES,AX			; POINT TO SEGMENT TO TEST
	CMP	WORD PTR ES:[DI],0FFFFH ; DID LOCATION 0 CHANGE?
	JZ	SD1			; CONTINUE IF NOT
	JMP	SHUT_8			; GO HALT IF YES
SD1:	RET

;------- CAUSE A SHUTDOWN

SD2:	MOV	AL,20H			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 20 <><>
	JMP	PROC_SHUTDOWN		; CAUSE A SHUTDOWN (RETURN VIA JUMP)
;--------------------------------------------------------
; RETURN 1 FROM SHUTDOWN				:
;--------------------------------------------------------

SHUT1:	MOV	AL,21H			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 21 <><>
	MOV	SP,STACK		; SET REAL MODE STACK
	MOV	SS,SP			;
	MOV	SP,OFFSET TOS		;

	MOV	AX,DATA 		; SET UP THE REAL DATA AREA
	MOV	DS,AX

;-------- GET THE CONFIGURATION FROM CMOS

	MOV	AL,DIAG_STATUS		; CHECK CMOS GOOD
	OUT	CMOS_PORT,AL		;
	JMP	SHORT $+2
	IN	AL,CMOS_PORT+1		; GET THE STATUS
	TEST	AL,0C0H 		; OK?
	JZ	M_OK			; GO IF YES
	JMP	BAD_MOS 		; GO IF NOT
M_OK:	MOV	AH,AL			; SAVE THE CMOS STATUS
	MOV	AL,DIAG_STATUS		; ADDRESS THE DIAG STATUS
	OUT	CMOS_PORT,AL		;
	XCHG	AL,AH			; RESTORE THE STATUS BYTE
	AND	AL,0DFH 		; CLEAR THE MIN CONFIG BIT
	OUT	CMOS_PORT+1,AL		;
	MOV	AL,C_EQUIP		; GET THE EQUIPMENT BYTE
	JMP	SHORT $+2		;
	OUT	CMOS_PORT,AL		;
	JMP	SHORT $+2		; IO DELAY
	IN	AL,CMOS_PORT+1		;

;-------- INSURE CONFIGURATION HAS CORRECT VIDEO TYPE

	MOV	AH,AL			; SAVE VIDEO TYPE
	TEST	AL,030H 		; ANY VIDEO?
	JNZ	MOS_OK_1		; CONTINUE
	CALL	CHK_VIDEO		; INSURE VIDEO ROM PRESENT
	JZ	MOS_OK			; CONTINUE

	TEST	MFG_TST,MFG_JMP 	; EXCEPT IF MFG JUMPER IS INSTALLED
	JZ	NORMAL_CONFIG		; GO IF INSTALLED

	JMP	BAD_MOS 		; GO DEFAULT
;-------- ROUTINE CHECK FOR VIDEO ROM PRESENT

CHK_VIDEO:
	MOV	CX,0C000H		; START OF IO ROM
CHK_VIDEO1:
	PUSH	AX			; SAVE THE CONFIG
	PUSH	DS			; SAVE THE DATA SEGMENT
	MOV	DS,CX			;
	SUB	BX,BX			; GET THE FIRST 2 LOCATIONS
	MOV	AX,[BX] 		;
	POP	DS			; RESTORE DATA SEG AND BUS SETTLE
	CMP	AX,0AA55H		; IS THE VIDEO ROM PRESENT?
	POP	AX			; GET THE CONFIG
	JZ	CHK_VIDEO2		; GO IF VIDEO ROM INSTALLED
	ADD	CX,080H 		; POINT TO NEXT 2K BLOCK
	CMP	CX,0C800H		; TOP OF VIDEO ROM AREA YET?
	JL	CHK_VIDEO1		; TRY AGAIN
	AND	CX,CX			; SET NON ZERO FLAG
CHK_VIDEO2:
	RET				; RETURN TO CALLER

;-------- CMOS VIDEO BITS NON ZERO (CHECK FOR PRIMARY DISPLAY AND NO VIDEO ROM)

MOS_OK_1:
	CALL	CHK_VIDEO		; IS THE VIDEO ROM INSTALLED?
	JZ	BAD_MOS 		; WRONG CONFIGURATION IN CONFIG BYTE


	MOV	AL,AH			; RESTORE CONFIGURATION
	TEST	MFG_TST,DSP_JMP 	; CHECK FOR DISPLAY JUMPER
	JZ	MOS_OK_2		; GO IF COLOR CARD IS PRIMARY DISPLAY

;-------- MONO CARD IS PRIMARY DISPLAY	   (NO JUMPER INSTALLED)

	AND	AL,30H			; INSURE MONO IS PRIMARY
	CMP	AL,30H			; CONFIG OK?
	JNZ	BAD_MOS 		; GO IF NOT
	MOV	AL,AH			; RESTORE CONFIGURATION
	JMP	MOS_OK			; USE THE CONFIG BYTE FOR CRT

;-------- COLOR CARD

MOS_OK_2:
	AND	AL,30H			; STRIP UNWANTED BITS
	CMP	AL,30H			; MUST NOT BE MONO WITH JUMPER INSTALLED
	MOV	AL,AH			; RESTORE CONFIGURATION
	JZ	BAD_MOS 		; GO IF YES

;-------- CONFIGURATION MUST HAVE AT LEAST ONE DISKETTE

MOS_OK: TEST	AL,01H			; MUST HAVE AT LEAST ONE DISKETTE
	JNZ	NORMAL_CONFIG		; GO SET CONFIGURATION IF OK
	TEST	MFG_TST,MFG_JMP 	; EXCEPT IF MFG JUMPER IS INSTALLED
	JZ	NORMAL_CONFIG		; GO IF INSTALLED

;-------- MINIMUM CONFIG WITH BAD CMOS OR NON VALID VIDEO

BAD_MOS:
	MOV	AL,DIAG_STATUS		; GET THE DIAGNOSTIC STATUS
	OUT	CMOS_PORT,AL		;
	JMP	SHORT $+2		;
	IN	AL,CMOS_PORT+1		;
	TEST	AL,0C0H 		; WAS BATTERY DEFECTIVE OR BAD CKSUM
	JNZ	BAD_MOS1		; GO IF YES
	XCHG	AL,AH			; SAVE THE STATUS
	MOV	AL,DIAG_STATUS		; CHECK CMOS GOOD
	OUT	CMOS_PORT,AL		;
	JMP	SHORT $+2		;
	XCHG	AL,AH			; RESTORE THE STATUS
	OR	AL,20H			; SET THE MIN CONFIG FLAG

	OUT	CMOS_PORT+1,AL		; STORE THE STATUS
BAD_MOS1:
	CALL	CHK_VIDEO		; CHECK FOR VIDEO ROM
	MOV	AL,01H			; DISKETTE ONLY
	JZ	NORMAL_CONFIG		; GO IF VIDEO ROM PRESENT

	TEST	MFG_TST,DSP_JMP 	; CHECK FOR DISPLAY JUMPER
	MOV	AL,11H			; DEFAULT TO 40X25 COLOR
	JZ	NORMAL_CONFIG		; GO IF JUMPER IS INSTALLED

	MOV	AL,31H			; DISKETTE / BW CRT 80X25
;----------------------------------------
;	CONFIGURATION AND MFG MODE	:
;----------------------------------------
NORMAL_CONFIG:

	TEST	MFG_TST,MFG_JMP 	; IS THE MANUFACTURING JUMPER INSTALLED
	JNZ	NORM1			; GO IF NOT
	AND	AL,03EH 		; STRIP DISKETTE FOR MFG TEST

NORM1:	SUB	AH,AH			;
	MOV	EQUIP_FLAG,AX		; SAVE SWITCH INFO
	CMP	RESET_FLAG,1234H	; BYPASS IF SOFT RESET
	JZ	E6			;

;------- GET THE FIRST SELF TEST RESULTS FROM KEYBOARD

	MOV	AL,60H			; ENABLE KEYBOARD
	CALL	C8042			; ISSUE WRITE BYTE COMMAND
	MOV	AL,4DH			; ENABLE OUT BUFF FULL INT
					; SYS FLAG, PC 1 COMP - INH OVERRIDE
	OUT	PORT_A,AL		; ENABLE KEYBOARD
					;

	SUB	CX,CX			; WAIT FOR COMMAND ACCEPTED
	CALL	C42_1			;

	MOV	CX,07FFFH		; SET LOOP COUNT FOR APPROX 100MS
					;  TO RESPOND
TST6:	IN	AL,STATUS_PORT		; WAIT FOR OUTPUT BUFF FULL
	TEST	AL,OUT_BUF_FULL 	;
	LOOPZ	TST6			; TRY AGAIN IF NOT

	PUSHF				; SAVE FLAGS
	MOV	AL,DIS_KBD		; DISABLE KEYBOARD
	CALL	C8042			; ISSUE THE COMMAND
	POPF				; RESTORE FLAGS
	JZ	E6			; CONTINUE WITHOUT RESULTS
	IN	AL,PORT_A		; GET INPUT FROM KEY BOARD
	MOV	BYTE PTR RESET_FLAG,AL	; TEMP SAVE FOR AA RECEIVED

;-------- CHECK FOR MFG REQUEST

	CMP	AL,065H 		; LOAD MFG. TEST REQUEST?
	JNE	E6
	JMP	MFG_BOOT		; GO TO BOOTSTRAP IF SO
;--------------------------------------------------------
; TEST.14						:
;	INITIALIZE AND START CRT CONTROLLER (6845)	:
;	TEST VIDEO READ/WRITE STORAGE.			:
; DESCRIPTION						:
;	RESET THE VIDEO ENABLE SIGNAL.			:
;	SELECT ALPHANUMERIC MODE, 40 * 25, B & W.	:
;	READ/WRITE DATA PATTERNS TO STG, CHECK STG	:
;	ADDRESSABILITY. 				:
; ERROR = 1 LONG AND 2 SHORT BEEPS			:
;--------------------------------------------------------

E6:
	MOV	AX,EQUIP_FLAG		; GET SENSE INFO
	PUSH	AX			; SAVE IT
	MOV	AL,30H
	MOV	EQUIP_FLAG,AX
	SUB	AH,AH
	INT	INT_VIDEO		; SEND INIT TO B/W CARD
	MOV	AL,20H
	MOV	EQUIP_FLAG,AX
	SUB	AH,AH			; AND INIT COLOR CARD
	INT	INT_VIDEO
	MOV	AX,0001H		; SET COLOR 40X25 MODE
	INT	INT_VIDEO
	POP	AX			; RECOVER REAL SWITCH INFO
	MOV	EQUIP_FLAG,AX		; RESTORE IT
	AND	AL,30H			; ISOLATE VIDEO SWS
	JNZ	E7			; VIDEO SWS SET TO 0?
	PUSH	DS			; SAVE THE DATA SEGMENT
	PUSH	AX			;
	SUB	AX,AX			; SET DATA SEGMENT TO 0
	MOV	DS,AX			;
	MOV	DI,OFFSET VIDEO_INT	; SET INT 10H TO DUMMY
	MOV	WORD PTR [DI],OFFSET DUMMY_RETURN  ; RETURN IF NO VIDEO CARD
	POP	AX			; RESTORE REGISTERS
	POP	DS			;
	JMP	E18_1			; BYPASS VIDEO TEST
E7:					; TEST_VIDEO:
	CMP	AL,30H			; B/W CARD ATTACHED?
	JE	E8			; YES - SET MODE FOR B/W CARD
	INC	AH			; SET COLOR MODE FOR COLOR CD
	CMP	AL,20H			; 80X25 MODE SELECTED?
	JNE	E8			; NO - SET MODE FOR 40X25
	MOV	AH,3			; SET MODE FOR 80X25
E8:	XCHG	AH,AL			; SET_MODE:
	PUSH	AX			; SAVE VIDEO MODE ON STACK
	SUB	AH,AH			; INITIALIZE TO ALPHANUMERIC MD
	INT	INT_VIDEO		; CALL VIDEO_IO
	POP	AX			; RESTORE VIDEO SENSE SWS IN AH
	PUSH	AX			; RESAVE VALUE
	MOV	BX,0B000H		; BEG VIDEO RAM ADDR B/W CD
	MOV	DX,3B8H 		; MODE REG FOR B/W
	MOV	CX,2048 		; RAM WORD CNT FOR B/W CD
	MOV	AL,1			; SET MODE FOR BW CARD
	CMP	AH,30H			; B/W VIDEO CARD ATTACHED?
	JE	E9			; YES - GO TEST VIDEO STG
	MOV	BH,0B8H 		; BEG VIDEO RAM ADDR COLOR CD
	MOV	DX,3D8H 		; MODE REG FOR COLOR CD
	MOV	CH,20H			; RAM WORD CNT FOR COLOR CD
	DEC	AL			; SET MODE TO 0 FOR COLOR CD
E9:					; TEST_VIDEO_STG:
	OUT	DX,AL			; DISABLE VIDEO FOR COLOR CD
	MOV	ES,BX			; POINT ES TO VIDEO RAM
	MOV	DS,BX			; POINT DS TO VIDEO RAM
	ROR	CX,1			; DIVIDE BY 2 FOR WORD COUNT
	CALL	STGTST_CNT		; GO TEST VIDEO R/W STG
	JNE	E17			; R/W STG FAILURE - BEEP SPK
;------------------------------------------------
; TEST.15					:
;	SETUP VIDEO DATA ON SCREEN FOR VIDEO	:
;	LINE TEST.				:
; DESCRIPTION					:
;	ENABLE VIDEO SIGNAL AND SET MODE.	:
;	DISPLAY A HORIZONTAL BAR ON SCREEN.	:
;------------------------------------------------
E10:
	MOV	AL,22H			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 22 <><>

	POP	AX			; GET VIDEO SENSE SWS (AH)
	PUSH	AX			; SAVE IT
	MOV	AH,0			; ENABLE VIDEO AND SET MODE
	INT	INT_VIDEO		; VIDEO
	MOV	AX,7020H		; WRT BLANKS IN REVERSE VIDEO
	SUB	DI,DI			; SETUP STARTING LOC
	MOV	CX,40			; NO. OF BLANKS TO DISPLAY
	REP	STOSW			; WRITE VIDEO STORAGE
;----------------------------------------
; TEST.16				:
;	CRT INTERFACE LINES TEST	:
; DESCRIPTION				:
;	SENSE ON/OFF TRANSITION OF THE	:
;	VIDEO ENABLE AND HORIZONTAL	:
;	SYNC LINES.			:
;----------------------------------------
	POP	AX			; GET VIDEO SENSE SW INFO
	PUSH	AX			; SAVE IT
	CMP	AH,30H			; B/W CARD ATTACHED?
	MOV	DX,03BAH		; SETUP ADDR OF BW STATUS PORT
	JE	E11			; YES - GO TEST LINES
	MOV	DX,03DAH		; COLOR CARD IS ATTACHED
E11:					; LINE_TST:
	MOV	AH,8
E12:					; OFLOOP_CNT:
	SUB	CX,CX
E13:	IN	AL,DX			; READ CRT STATUS PORT
	AND	AL,AH			; CHECK VIDEO/HORZ LINE
	JNZ	E14			; ITS ON - CHECK IF IT GOES OFF
	LOOP	E13			; LOOP TILL ON OR TIMEOUT
	JMP	SHORT E17		; GO PRINT ERROR MSG
E14:	SUB	CX,CX
E15:	IN	AL,DX			; READ CRT STATUS PORT
	AND	AL,AH			; CHECK VIDEO/HORZ LINE
	JZ	E16			; ITS ON - CHECK NEXT LINE
	LOOP	E15			; LOOP IF ON TILL IT GOES OFF
	JMP	E17			; GO ERROR BEEP

;------- CHECK HORIZONTAL LINE

E16:	MOV	CL,3			; GET NEXT BIT TO CHECK
	SHR	AH,CL
	JNZ	E12			; CONTINUE
E18:					; DISPLAY_CURSOR:
	POP	AX			; GET VIDEO SENSE SWS (AH)
	MOV	AH,0			; SET MODE AND DISPLAY CURSOR
	INT	INT_VIDEO		; CALL VIDEO I/O PROCEDURE

	;--------- CHECK FOR THE ADVANCED VIDEO CARD

E18_1:	MOV	DX,0C000H		; SET THE LOW SEGMENT VALUE
E18A:	MOV	AL,23H			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 23 <><>
	MOV	DS,DX
	SUB	BX,BX
	MOV	AX,[BX] 		; GET FIRST 2 LOCATIONS
	PUSH	BX
	POP	BX			; LET BUS SETTLE
	CMP	AX,0AA55H		; PRESENT?
	JNZ	E18B			; NO? GO LOOK FOR OTHER MODULES
	CALL	ROM_CHECK		; GO SCAN MODULE
	JMP	SHORT E18C
E18B:	ADD	DX,0080H		; POINT TO NEXT 2K BLOCK
E18C:	CMP	DX,0C800H		; TOP OF VIDEO ROM AREA YET?
	JL	E18A			; GO SCAN FOR ANOTHER MODULE
	MOV	AL,24H			; <><><><><><><><><><><><>
	OUT	MFG_PORT,AL		; <><><>CHECKPOINT 24 <><>
	JMP	POST2			; GO TO NEXT TEST

;-------- CRT ERROR SET MFG CKPT AND ERR BEEP

E17:	CALL	DDS			; POINT TO DATA

;-------- CHECKPOINT 0C = MONO FAILED

	MOV	MFG_ERR_FLAG,0CH	;<><><><>CRT ERR CHKPT. 0C<><>
	CMP	BYTE PTR RESET_FLAG,064H ; IS THIS A MFG REQUEST?
	JZ	E19			; BY PASS ERROR BEEP IF YES
	TEST	MFG_TST,MFG_JMP 	; IS THE MFG LOOP JUMPER INSTALLED?
	JZ	E19			; BY PASS ERROR BEEP IF YES
	MOV	DX,102H
	CALL	ERR_BEEP		; GO BEEP SPEAKER
E19:	PUSH	DS
	MOV	AX,EQUIP_FLAG		; GET THE CURRENT VIDEO
	AND	AL,30H			; STRIP OTHER BITS
	CMP	AL,30H			; IS IT MONO?
	JZ	TRY_COLOR		; GO IF YES
;-----	COLOR FAILED TRY MONO

;------- CHECKPOINT 0D = COLOR FAILED

	MOV	MFG_ERR_FLAG,0DH	;<><><><>CRT ERR CHKPT. 0D<><>

	MOV	DX,3B8H 		; DISABLE B/W
	MOV	AL,1			;
	OUT	DX,AL			; OUTPUT THE DISABLE
	MOV	BX,0B000H		; CHECK FOR MONO VIDEO RAM
	MOV	DS,BX			;
	MOV	AX,0AA55H		; WRITE AN AA55
	SUB	BX,BX			;  TO THE FIRST LOCATION
	MOV	[BX],AX 		;
	JMP	SHORT $+2		; ALLOW BUS TO SETTLE
	MOV	AX,[BX] 		; READ THE FIRST LOCATION
	CMP	AX,0AA55H		; IS THE MONO VIDEO CARD THERE?
	POP	DS			; RESTORE THE DATA SEGMENT
	JNZ	E17_3			; GO IF NOT
	OR	EQUIP_FLAG,30H		; TURN ON MONO BITS IN EQUIP FLAG
	MOV	AX,EQUIP_FLAG		; ENABLE VIDEO
	SUB	AH,AH			;
	INT	INT_VIDEO		;
	JMP	E17_1			; CONTINUE

;-------- MONO FAILED TRY COLOR

TRY_COLOR:
	MOV	AL,01H			; SET MODE COLOR 40X25
	SUB	AH,AH			;
	INT	INT_VIDEO		;
	MOV	DX,3D8H 		; DISABLE COLOR
	MOV	AL,0			;
	OUT	DX,AL			; OUTPUT THE DISABLE
	MOV	BX,0B800H		; CHECK FOR COLOR VIDEO RAM
	MOV	DS,BX			;
	MOV	AX,0AA55H		; WRITE AN AA55
	SUB	BX,BX			;  TO THE FIRST LOCATION
	MOV	[BX],AX 		;
	JMP	SHORT $+2		; ALLOW BUS TO SETTLE
	MOV	AX,[BX] 		; READ THE FIRST LOCATION
	CMP	AX,0AA55H		; IS THE COLOR VIDEO CARD THERE?
	POP	DS			; RESTORE THE DATA SEGMENT
	JNZ	E17_3			; GO IF NOT
	AND	EQUIP_FLAG,0FFCFH	; TURN OFF VIDEO BITS
	OR	EQUIP_FLAG,10H		; SET COLOR 40X24
	MOV	AL,01H			;
	SUB	AH,AH			;
	INT	INT_VIDEO		;
E17_1:
	POP	AX			; SET NEW VIDEO TYPE ON STACK
	MOV	AX,EQUIP_FLAG		;
	AND	AL,30H			;
	CMP	AL,30H			; IS IT THE B/W?
	SUB	AL,AL			;
	JZ	E17_2			; GO IF YES
	INC	AL			; INIT FOR 40X25
E17_2:	PUSH	AX
E17_4:	JMP	E18

;------- BOTH VIDEO CARDS FAILED SET DUMMY RETURN IF RETRACE FAILURE

E17_3:
	PUSH	DS			;
	SUB	AX,AX			; SET DS SEGMENT TO 0
	MOV	DS,AX
	MOV	DI,OFFSET VIDEO_INT	; SET INT 10H TO DUMMY
	MOV	WORD PTR [DI],OFFSET DUMMY_RETURN  ; RETURN IF NO VIDEO CARD
	POP	DS
	JMP	E18_1			; BYPASS REST OF VIDEO TEST
POST1	ENDP
CODE	ENDS
	END
